| ... | ... |
@@ -72,16 +72,6 @@ RUN cd /usr/local/lvm2 \ |
| 72 | 72 |
&& make install_device-mapper |
| 73 | 73 |
# see https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL |
| 74 | 74 |
|
| 75 |
-# Install lxc |
|
| 76 |
-ENV LXC_VERSION 1.1.2 |
|
| 77 |
-RUN mkdir -p /usr/src/lxc \ |
|
| 78 |
- && curl -sSL https://linuxcontainers.org/downloads/lxc/lxc-${LXC_VERSION}.tar.gz | tar -v -C /usr/src/lxc/ -xz --strip-components=1
|
|
| 79 |
-RUN cd /usr/src/lxc \ |
|
| 80 |
- && ./configure \ |
|
| 81 |
- && make \ |
|
| 82 |
- && make install \ |
|
| 83 |
- && ldconfig |
|
| 84 |
- |
|
| 85 | 75 |
# Install Go |
| 86 | 76 |
ENV GO_VERSION 1.5.1 |
| 87 | 77 |
RUN curl -sSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar -v -C /usr/local -xz
|
| ... | ... |
@@ -39,16 +39,6 @@ RUN cd /usr/local/lvm2 \ |
| 39 | 39 |
&& make install_device-mapper |
| 40 | 40 |
# see https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL |
| 41 | 41 |
|
| 42 |
-# Install lxc |
|
| 43 |
-ENV LXC_VERSION 1.1.2 |
|
| 44 |
-RUN mkdir -p /usr/src/lxc \ |
|
| 45 |
- && curl -sSL https://linuxcontainers.org/downloads/lxc/lxc-${LXC_VERSION}.tar.gz | tar -v -C /usr/src/lxc/ -xz --strip-components=1
|
|
| 46 |
-RUN cd /usr/src/lxc \ |
|
| 47 |
- && ./configure \ |
|
| 48 |
- && make \ |
|
| 49 |
- && make install \ |
|
| 50 |
- && ldconfig |
|
| 51 |
- |
|
| 52 | 42 |
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor |
| 53 | 43 |
|
| 54 | 44 |
# Get the "docker-py" source so we can run their integration tests |
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
(from "ubuntu:14.04") |
| 2 | 2 |
(maintainer "Tianon Gravi <admwiggin@gmail.com> (@tianon)") |
| 3 |
-(run "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yq \tapt-utils \taufs-tools \tautomake \tbtrfs-tools \tbuild-essential \tcurl \tdpkg-sig \tgit \tiptables \tlibapparmor-dev \tlibcap-dev \tlibsqlite3-dev \tlxc=1.0* \tmercurial \tpandoc \tparallel \treprepro \truby1.9.1 \truby1.9.1-dev \ts3cmd=1.1.0* \t--no-install-recommends") |
|
| 3 |
+(run "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yq \tapt-utils \taufs-tools \tautomake \tbtrfs-tools \tbuild-essential \tcurl \tdpkg-sig \tgit \tiptables \tlibapparmor-dev \tlibcap-dev \tlibsqlite3-dev \tmercurial \tpandoc \tparallel \treprepro \truby1.9.1 \truby1.9.1-dev \ts3cmd=1.1.0* \t--no-install-recommends") |
|
| 4 | 4 |
(run "git clone --no-checkout https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103") |
| 5 | 5 |
(run "cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper") |
| 6 | 6 |
(run "curl -sSL https://golang.org/dl/go1.3.src.tar.gz | tar -v -C /usr/local -xz") |
| ... | ... |
@@ -659,7 +659,6 @@ _docker_daemon() {
|
| 659 | 659 |
--dns |
| 660 | 660 |
--dns-search |
| 661 | 661 |
--dns-opt |
| 662 |
- --exec-driver -e |
|
| 663 | 662 |
--exec-opt |
| 664 | 663 |
--exec-root |
| 665 | 664 |
--fixed-cidr |
| ... | ... |
@@ -1379,7 +1378,6 @@ _docker_run() {
|
| 1379 | 1379 |
--link |
| 1380 | 1380 |
--log-driver |
| 1381 | 1381 |
--log-opt |
| 1382 |
- --lxc-conf |
|
| 1383 | 1382 |
--mac-address |
| 1384 | 1383 |
--memory -m |
| 1385 | 1384 |
--memory-swap |
| ... | ... |
@@ -51,7 +51,6 @@ complete -c docker -f -n '__fish_docker_no_subcommand' -s d -l daemon -d 'Enable |
| 51 | 51 |
complete -c docker -f -n '__fish_docker_no_subcommand' -l dns -d 'Force Docker to use specific DNS servers' |
| 52 | 52 |
complete -c docker -f -n '__fish_docker_no_subcommand' -l dns-opt -d 'Force Docker to use specific DNS options' |
| 53 | 53 |
complete -c docker -f -n '__fish_docker_no_subcommand' -l dns-search -d 'Force Docker to use specific DNS search domains' |
| 54 |
-complete -c docker -f -n '__fish_docker_no_subcommand' -s e -l exec-driver -d 'Force the Docker runtime to use a specific exec driver' |
|
| 55 | 54 |
complete -c docker -f -n '__fish_docker_no_subcommand' -l exec-opt -d 'Set exec driver options' |
| 56 | 55 |
complete -c docker -f -n '__fish_docker_no_subcommand' -l fixed-cidr -d 'IPv4 subnet for fixed IPs (e.g. 10.20.0.0/16)' |
| 57 | 56 |
complete -c docker -f -n '__fish_docker_no_subcommand' -l fixed-cidr-v6 -d 'IPv6 subnet for fixed IPs (e.g.: 2001:a02b/48)' |
| ... | ... |
@@ -135,7 +134,6 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l help -d 'Pri |
| 135 | 135 |
complete -c docker -A -f -n '__fish_seen_subcommand_from create' -s i -l interactive -d 'Keep STDIN open even if not attached' |
| 136 | 136 |
complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l ipc -d 'Default is to create a private IPC namespace (POSIX SysV IPC) for the container' |
| 137 | 137 |
complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l link -d 'Add link to another container in the form of <name|id>:alias' |
| 138 |
-complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l lxc-conf -d '(lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"' |
|
| 139 | 138 |
complete -c docker -A -f -n '__fish_seen_subcommand_from create' -s m -l memory -d 'Memory limit (format: <number>[<unit>], where unit = b, k, m or g)' |
| 140 | 139 |
complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l mac-address -d 'Container MAC address (e.g. 92:d0:c6:0a:29:33)' |
| 141 | 140 |
complete -c docker -A -f -n '__fish_seen_subcommand_from create' -l memory-swap -d "Total memory usage (memory + swap), set '-1' to disable swap (format: <number>[<unit>], where unit = b, k, m or g)" |
| ... | ... |
@@ -324,7 +322,6 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l help -d 'Print |
| 324 | 324 |
complete -c docker -A -f -n '__fish_seen_subcommand_from run' -s i -l interactive -d 'Keep STDIN open even if not attached' |
| 325 | 325 |
complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l ipc -d 'Default is to create a private IPC namespace (POSIX SysV IPC) for the container' |
| 326 | 326 |
complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l link -d 'Add link to another container in the form of <name|id>:alias' |
| 327 |
-complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l lxc-conf -d '(lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"' |
|
| 328 | 327 |
complete -c docker -A -f -n '__fish_seen_subcommand_from run' -s m -l memory -d 'Memory limit (format: <number>[<unit>], where unit = b, k, m or g)' |
| 329 | 328 |
complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l mac-address -d 'Container MAC address (e.g. 92:d0:c6:0a:29:33)' |
| 330 | 329 |
complete -c docker -A -f -n '__fish_seen_subcommand_from run' -l memory-swap -d "Total memory usage (memory + swap), set '-1' to disable swap (format: <number>[<unit>], where unit = b, k, m or g)" |
| ... | ... |
@@ -438,7 +438,6 @@ __docker_subcommand() {
|
| 438 | 438 |
"($help)*"{-l=,--label=}"[Set meta data on a container]:label: "
|
| 439 | 439 |
"($help)--log-driver=[Default driver for container logs]:Logging driver:(json-file syslog journald gelf fluentd awslogs splunk none)" |
| 440 | 440 |
"($help)*--log-opt=[Log driver specific options]:log driver options: " |
| 441 |
- "($help)*--lxc-conf=[Add custom lxc options]:lxc options: " |
|
| 442 | 441 |
"($help)--mac-address=[Container MAC address]:MAC address: " |
| 443 | 442 |
"($help)--name=[Container name]:name: " |
| 444 | 443 |
"($help)--net=[Connect a container to a network]:network mode:(bridge none container host)" |
| ... | ... |
@@ -541,7 +540,6 @@ __docker_subcommand() {
|
| 541 | 541 |
"($help)*--dns-opt=[DNS options to use]:DNS option: " \ |
| 542 | 542 |
"($help)*--default-ulimit=[Set default ulimit settings for containers]:ulimit: " \ |
| 543 | 543 |
"($help)--disable-legacy-registry[Do not contact legacy registries]" \ |
| 544 |
- "($help -e --exec-driver)"{-e=,--exec-driver=}"[Exec driver to use]:driver:(native lxc windows)" \
|
|
| 545 | 544 |
"($help)*--exec-opt=[Set exec driver options]:exec driver options: " \ |
| 546 | 545 |
"($help)--exec-root=[Root of the Docker execdriver]:path:_directories" \ |
| 547 | 546 |
"($help)--fixed-cidr=[IPv4 subnet for fixed IPs]:IPv4 subnet: " \ |
| ... | ... |
@@ -14,10 +14,6 @@ |
| 14 | 14 |
/var/run/docker\.sock -s gen_context(system_u:object_r:docker_var_run_t,s0) |
| 15 | 15 |
/var/run/docker-client(/.*)? gen_context(system_u:object_r:docker_var_run_t,s0) |
| 16 | 16 |
|
| 17 |
-/var/lock/lxc(/.*)? gen_context(system_u:object_r:docker_lock_t,s0) |
|
| 18 |
- |
|
| 19 |
-/var/log/lxc(/.*)? gen_context(system_u:object_r:docker_log_t,s0) |
|
| 20 |
- |
|
| 21 | 17 |
/var/lib/docker/init(/.*)? gen_context(system_u:object_r:docker_share_t,s0) |
| 22 | 18 |
/var/lib/docker/containers/.*/hosts gen_context(system_u:object_r:docker_share_t,s0) |
| 23 | 19 |
/var/lib/docker/containers/.*/hostname gen_context(system_u:object_r:docker_share_t,s0) |
| ... | ... |
@@ -292,7 +292,6 @@ interface(`docker_filetrans_named_content',` |
| 292 | 292 |
files_pid_filetrans($1, docker_var_run_t, file, "docker.pid") |
| 293 | 293 |
files_pid_filetrans($1, docker_var_run_t, sock_file, "docker.sock") |
| 294 | 294 |
files_pid_filetrans($1, docker_var_run_t, dir, "docker-client") |
| 295 |
- logging_log_filetrans($1, docker_log_t, dir, "lxc") |
|
| 296 | 295 |
files_var_lib_filetrans($1, docker_var_lib_t, dir, "docker") |
| 297 | 296 |
filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "config.env") |
| 298 | 297 |
filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "hosts") |
| ... | ... |
@@ -406,11 +405,6 @@ interface(`staff_stub',` |
| 406 | 406 |
type staff_t; |
| 407 | 407 |
') |
| 408 | 408 |
') |
| 409 |
-interface(`virt_stub_lxc',` |
|
| 410 |
- gen_require(` |
|
| 411 |
- type virtd_lxc_t; |
|
| 412 |
- ') |
|
| 413 |
-') |
|
| 414 | 409 |
interface(`virt_stub_svirt_sandbox_domain',` |
| 415 | 410 |
gen_require(` |
| 416 | 411 |
attribute svirt_sandbox_domain; |
| ... | ... |
@@ -90,7 +90,6 @@ files_etc_filetrans(docker_t, docker_config_t, dir, "docker") |
| 90 | 90 |
|
| 91 | 91 |
manage_dirs_pattern(docker_t, docker_lock_t, docker_lock_t) |
| 92 | 92 |
manage_files_pattern(docker_t, docker_lock_t, docker_lock_t) |
| 93 |
-files_lock_filetrans(docker_t, docker_lock_t, { dir file }, "lxc")
|
|
| 94 | 93 |
|
| 95 | 94 |
manage_dirs_pattern(docker_t, docker_log_t, docker_log_t) |
| 96 | 95 |
manage_files_pattern(docker_t, docker_log_t, docker_log_t) |
| ... | ... |
@@ -213,10 +212,6 @@ optional_policy(` |
| 213 | 213 |
openvswitch_stream_connect(docker_t) |
| 214 | 214 |
') |
| 215 | 215 |
|
| 216 |
-# |
|
| 217 |
-# lxc rules |
|
| 218 |
-# |
|
| 219 |
- |
|
| 220 | 216 |
allow docker_t self:capability { dac_override setgid setpcap setuid sys_admin sys_boot sys_chroot sys_ptrace };
|
| 221 | 217 |
|
| 222 | 218 |
allow docker_t self:process { getcap setcap setexec setpgid setsched signal_perms };
|
| ... | ... |
@@ -317,7 +312,6 @@ optional_policy(` |
| 317 | 317 |
virt_exec_sandbox_files(docker_t) |
| 318 | 318 |
virt_manage_sandbox_files(docker_t) |
| 319 | 319 |
virt_relabel_sandbox_filesystem(docker_t) |
| 320 |
- # for lxc |
|
| 321 | 320 |
virt_transition_svirt_sandbox(docker_t, system_r) |
| 322 | 321 |
virt_mounton_sandbox_file(docker_t) |
| 323 | 322 |
# virt_attach_sandbox_tun_iface(docker_t) |
| ... | ... |
@@ -388,11 +382,6 @@ optional_policy(` |
| 388 | 388 |
') |
| 389 | 389 |
|
| 390 | 390 |
optional_policy(` |
| 391 |
- virt_stub_lxc() |
|
| 392 |
- docker_exec_lib(virtd_lxc_t) |
|
| 393 |
-') |
|
| 394 |
- |
|
| 395 |
-optional_policy(` |
|
| 396 | 391 |
virt_stub_svirt_sandbox_domain() |
| 397 | 392 |
virt_stub_svirt_sandbox_file() |
| 398 | 393 |
allow svirt_sandbox_domain self:netlink_kobject_uevent_socket create_socket_perms; |
| 399 | 394 |
deleted file mode 100755 |
| ... | ... |
@@ -1,77 +0,0 @@ |
| 1 |
-#!/usr/bin/perl |
|
| 2 |
-# |
|
| 3 |
-# A simple helper script to help people build seccomp profiles for |
|
| 4 |
-# Docker/LXC. The goal is mostly to reduce the attack surface to the |
|
| 5 |
-# kernel, by restricting access to rarely used, recently added or not used |
|
| 6 |
-# syscalls. |
|
| 7 |
-# |
|
| 8 |
-# This script processes one or more files which contain the list of system |
|
| 9 |
-# calls to be allowed. See mkseccomp.sample for more information how you |
|
| 10 |
-# can configure the list of syscalls. When run, this script produces output |
|
| 11 |
-# which, when stored in a file, can be passed to docker as follows: |
|
| 12 |
-# |
|
| 13 |
-# docker run --lxc-conf="lxc.seccomp=$file" <rest of arguments> |
|
| 14 |
-# |
|
| 15 |
-# The included sample file shows how to cut about a quarter of all syscalls, |
|
| 16 |
-# which affecting most applications. |
|
| 17 |
-# |
|
| 18 |
-# For specific situations it is possible to reduce the list further. By |
|
| 19 |
-# reducing the list to just those syscalls required by a certain application |
|
| 20 |
-# you can make it difficult for unknown/unexpected code to run. |
|
| 21 |
-# |
|
| 22 |
-# Run this script as follows: |
|
| 23 |
-# |
|
| 24 |
-# ./mkseccomp.pl < mkseccomp.sample >syscalls.list |
|
| 25 |
-# or |
|
| 26 |
-# ./mkseccomp.pl mkseccomp.sample >syscalls.list |
|
| 27 |
-# |
|
| 28 |
-# Multiple files can be specified, in which case the lists of syscalls are |
|
| 29 |
-# combined. |
|
| 30 |
-# |
|
| 31 |
-# By Martijn van Oosterhout <kleptog@svana.org> Nov 2013 |
|
| 32 |
- |
|
| 33 |
-# How it works: |
|
| 34 |
-# |
|
| 35 |
-# This program basically spawns two processes to form a chain like: |
|
| 36 |
-# |
|
| 37 |
-# <process data section to prefix __NR_> | cpp | <add header and filter unknown syscalls> |
|
| 38 |
- |
|
| 39 |
-use strict; |
|
| 40 |
-use warnings; |
|
| 41 |
- |
|
| 42 |
-if( -t ) {
|
|
| 43 |
- print STDERR "Helper script to make seccomp filters for Docker/LXC.\n"; |
|
| 44 |
- print STDERR "Usage: mkseccomp.pl < [files...]\n"; |
|
| 45 |
- exit 1; |
|
| 46 |
-} |
|
| 47 |
- |
|
| 48 |
-my $pid = open(my $in, "-|") // die "Couldn't fork1 ($!)\n"; |
|
| 49 |
- |
|
| 50 |
-if($pid == 0) { # Child
|
|
| 51 |
- $pid = open(my $out, "|-") // die "Couldn't fork2 ($!)\n"; |
|
| 52 |
- |
|
| 53 |
- if($pid == 0) { # Child, which execs cpp
|
|
| 54 |
- exec "cpp" or die "Couldn't exec cpp ($!)\n"; |
|
| 55 |
- exit 1; |
|
| 56 |
- } |
|
| 57 |
- |
|
| 58 |
- # Process the DATA section and output to cpp |
|
| 59 |
- print $out "#include <sys/syscall.h>\n"; |
|
| 60 |
- while(<>) {
|
|
| 61 |
- if(/^\w/) {
|
|
| 62 |
- print $out "__NR_$_"; |
|
| 63 |
- } |
|
| 64 |
- } |
|
| 65 |
- close $out; |
|
| 66 |
- exit 0; |
|
| 67 |
- |
|
| 68 |
-} |
|
| 69 |
- |
|
| 70 |
-# Print header and then process output from cpp. |
|
| 71 |
-print "1\n"; |
|
| 72 |
-print "whitelist\n"; |
|
| 73 |
- |
|
| 74 |
-while(<$in>) {
|
|
| 75 |
- print if( /^[0-9]/ ); |
|
| 76 |
-} |
|
| 77 |
- |
| 78 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,444 +0,0 @@ |
| 1 |
-/* This sample file is an example for mkseccomp.pl to produce a seccomp file |
|
| 2 |
- * which restricts syscalls that are only useful for an admin but allows the |
|
| 3 |
- * vast majority of normal userspace programs to run normally. |
|
| 4 |
- * |
|
| 5 |
- * The format of this file is one line per syscall. This is then processed |
|
| 6 |
- * and passed to 'cpp' to convert the names to numbers using whatever is |
|
| 7 |
- * correct for your platform. As such C-style comments are permitted. Note |
|
| 8 |
- * this also means that C preprocessor macros are also allowed. So it is |
|
| 9 |
- * possible to create groups surrounded by #ifdef/#endif and control their |
|
| 10 |
- * inclusion via #define (not #include). |
|
| 11 |
- * |
|
| 12 |
- * Syscalls that don't exist on your architecture are silently filtered out. |
|
| 13 |
- * Syscalls marked with (*) are required for a container to spawn a bash |
|
| 14 |
- * shell successfully (not necessarily full featured). Listing the same |
|
| 15 |
- * syscall multiple times is no problem. |
|
| 16 |
- * |
|
| 17 |
- * If you want to make a list specifically for one application the easiest |
|
| 18 |
- * way is to run the application under strace, like so: |
|
| 19 |
- * |
|
| 20 |
- * $ strace -f -q -c -o strace.out application args... |
|
| 21 |
- * |
|
| 22 |
- * Once you have a reasonable sample of the execution of the program, exit |
|
| 23 |
- * it. The file strace.out will have a summary of the syscalls used. Copy |
|
| 24 |
- * that list into this file, comment out everything else except the starred |
|
| 25 |
- * syscalls (which you need for the container to start) and you're done. |
|
| 26 |
- * |
|
| 27 |
- * To get the list of syscalls from the strace output this works well for |
|
| 28 |
- * me |
|
| 29 |
- * |
|
| 30 |
- * $ cut -c52 < strace.out |
|
| 31 |
- * |
|
| 32 |
- * This sample list was compiled as a combination of all the syscalls |
|
| 33 |
- * available on i386 and amd64 on Ubuntu Precise, as such it may not contain |
|
| 34 |
- * everything and not everything may be relevant for your system. This |
|
| 35 |
- * shouldn't be a problem. |
|
| 36 |
- */ |
|
| 37 |
- |
|
| 38 |
-// Filesystem/File descriptor related |
|
| 39 |
-access // (*) |
|
| 40 |
-chdir // (*) |
|
| 41 |
-chmod |
|
| 42 |
-chown |
|
| 43 |
-chown32 |
|
| 44 |
-close // (*) |
|
| 45 |
-creat |
|
| 46 |
-dup // (*) |
|
| 47 |
-dup2 // (*) |
|
| 48 |
-dup3 |
|
| 49 |
-epoll_create |
|
| 50 |
-epoll_create1 |
|
| 51 |
-epoll_ctl |
|
| 52 |
-epoll_ctl_old |
|
| 53 |
-epoll_pwait |
|
| 54 |
-epoll_wait |
|
| 55 |
-epoll_wait_old |
|
| 56 |
-eventfd |
|
| 57 |
-eventfd2 |
|
| 58 |
-faccessat // (*) |
|
| 59 |
-fadvise64 |
|
| 60 |
-fadvise64_64 |
|
| 61 |
-fallocate |
|
| 62 |
-fanotify_init |
|
| 63 |
-fanotify_mark |
|
| 64 |
-ioctl // (*) |
|
| 65 |
-fchdir |
|
| 66 |
-fchmod |
|
| 67 |
-fchmodat |
|
| 68 |
-fchown |
|
| 69 |
-fchown32 |
|
| 70 |
-fchownat |
|
| 71 |
-fcntl // (*) |
|
| 72 |
-fcntl64 |
|
| 73 |
-fdatasync |
|
| 74 |
-fgetxattr |
|
| 75 |
-flistxattr |
|
| 76 |
-flock |
|
| 77 |
-fremovexattr |
|
| 78 |
-fsetxattr |
|
| 79 |
-fstat // (*) |
|
| 80 |
-fstat64 |
|
| 81 |
-fstatat64 |
|
| 82 |
-fstatfs |
|
| 83 |
-fstatfs64 |
|
| 84 |
-fsync |
|
| 85 |
-ftruncate |
|
| 86 |
-ftruncate64 |
|
| 87 |
-getcwd // (*) |
|
| 88 |
-getdents // (*) |
|
| 89 |
-getdents64 |
|
| 90 |
-getxattr |
|
| 91 |
-inotify_add_watch |
|
| 92 |
-inotify_init |
|
| 93 |
-inotify_init1 |
|
| 94 |
-inotify_rm_watch |
|
| 95 |
-io_cancel |
|
| 96 |
-io_destroy |
|
| 97 |
-io_getevents |
|
| 98 |
-io_setup |
|
| 99 |
-io_submit |
|
| 100 |
-lchown |
|
| 101 |
-lchown32 |
|
| 102 |
-lgetxattr |
|
| 103 |
-link |
|
| 104 |
-linkat |
|
| 105 |
-listxattr |
|
| 106 |
-llistxattr |
|
| 107 |
-llseek |
|
| 108 |
-_llseek |
|
| 109 |
-lremovexattr |
|
| 110 |
-lseek // (*) |
|
| 111 |
-lsetxattr |
|
| 112 |
-lstat |
|
| 113 |
-lstat64 |
|
| 114 |
-mkdir |
|
| 115 |
-mkdirat |
|
| 116 |
-mknod |
|
| 117 |
-mknodat |
|
| 118 |
-newfstatat |
|
| 119 |
-_newselect |
|
| 120 |
-oldfstat |
|
| 121 |
-oldlstat |
|
| 122 |
-oldolduname |
|
| 123 |
-oldstat |
|
| 124 |
-olduname |
|
| 125 |
-oldwait4 |
|
| 126 |
-open // (*) |
|
| 127 |
-openat // (*) |
|
| 128 |
-pipe // (*) |
|
| 129 |
-pipe2 |
|
| 130 |
-poll |
|
| 131 |
-ppoll |
|
| 132 |
-pread64 |
|
| 133 |
-preadv |
|
| 134 |
-futimesat |
|
| 135 |
-pselect6 |
|
| 136 |
-pwrite64 |
|
| 137 |
-pwritev |
|
| 138 |
-read // (*) |
|
| 139 |
-readahead |
|
| 140 |
-readdir |
|
| 141 |
-readlink |
|
| 142 |
-readlinkat |
|
| 143 |
-readv |
|
| 144 |
-removexattr |
|
| 145 |
-rename |
|
| 146 |
-renameat |
|
| 147 |
-rmdir |
|
| 148 |
-select |
|
| 149 |
-sendfile |
|
| 150 |
-sendfile64 |
|
| 151 |
-setxattr |
|
| 152 |
-splice |
|
| 153 |
-stat // (*) |
|
| 154 |
-stat64 |
|
| 155 |
-statfs // (*) |
|
| 156 |
-statfs64 |
|
| 157 |
-symlink |
|
| 158 |
-symlinkat |
|
| 159 |
-sync |
|
| 160 |
-sync_file_range |
|
| 161 |
-sync_file_range2 |
|
| 162 |
-syncfs |
|
| 163 |
-tee |
|
| 164 |
-truncate |
|
| 165 |
-truncate64 |
|
| 166 |
-umask |
|
| 167 |
-unlink |
|
| 168 |
-unlinkat |
|
| 169 |
-ustat |
|
| 170 |
-utime |
|
| 171 |
-utimensat |
|
| 172 |
-utimes |
|
| 173 |
-write // (*) |
|
| 174 |
-writev |
|
| 175 |
- |
|
| 176 |
-// Network related |
|
| 177 |
-accept |
|
| 178 |
-accept4 |
|
| 179 |
-bind // (*) |
|
| 180 |
-connect // (*) |
|
| 181 |
-getpeername |
|
| 182 |
-getsockname // (*) |
|
| 183 |
-getsockopt |
|
| 184 |
-listen |
|
| 185 |
-recv |
|
| 186 |
-recvfrom // (*) |
|
| 187 |
-recvmmsg |
|
| 188 |
-recvmsg |
|
| 189 |
-send |
|
| 190 |
-sendmmsg |
|
| 191 |
-sendmsg |
|
| 192 |
-sendto // (*) |
|
| 193 |
-setsockopt |
|
| 194 |
-shutdown |
|
| 195 |
-socket // (*) |
|
| 196 |
-socketcall |
|
| 197 |
-socketpair |
|
| 198 |
-sethostname // (*) |
|
| 199 |
- |
|
| 200 |
-// Signal related |
|
| 201 |
-pause |
|
| 202 |
-rt_sigaction // (*) |
|
| 203 |
-rt_sigpending |
|
| 204 |
-rt_sigprocmask // (*) |
|
| 205 |
-rt_sigqueueinfo |
|
| 206 |
-rt_sigreturn // (*) |
|
| 207 |
-rt_sigsuspend |
|
| 208 |
-rt_sigtimedwait |
|
| 209 |
-rt_tgsigqueueinfo |
|
| 210 |
-sigaction |
|
| 211 |
-sigaltstack // (*) |
|
| 212 |
-signal |
|
| 213 |
-signalfd |
|
| 214 |
-signalfd4 |
|
| 215 |
-sigpending |
|
| 216 |
-sigprocmask |
|
| 217 |
-sigreturn |
|
| 218 |
-sigsuspend |
|
| 219 |
- |
|
| 220 |
-// Other needed POSIX |
|
| 221 |
-alarm |
|
| 222 |
-brk // (*) |
|
| 223 |
-clock_adjtime |
|
| 224 |
-clock_getres |
|
| 225 |
-clock_gettime |
|
| 226 |
-clock_nanosleep |
|
| 227 |
-//clock_settime |
|
| 228 |
-gettimeofday |
|
| 229 |
-nanosleep |
|
| 230 |
-nice |
|
| 231 |
-sysinfo |
|
| 232 |
-syslog |
|
| 233 |
-time |
|
| 234 |
-timer_create |
|
| 235 |
-timer_delete |
|
| 236 |
-timerfd_create |
|
| 237 |
-timerfd_gettime |
|
| 238 |
-timerfd_settime |
|
| 239 |
-timer_getoverrun |
|
| 240 |
-timer_gettime |
|
| 241 |
-timer_settime |
|
| 242 |
-times |
|
| 243 |
-uname // (*) |
|
| 244 |
- |
|
| 245 |
-// Memory control |
|
| 246 |
-madvise |
|
| 247 |
-mbind |
|
| 248 |
-mincore |
|
| 249 |
-mlock |
|
| 250 |
-mlockall |
|
| 251 |
-mmap // (*) |
|
| 252 |
-mmap2 |
|
| 253 |
-mprotect // (*) |
|
| 254 |
-mremap |
|
| 255 |
-msync |
|
| 256 |
-munlock |
|
| 257 |
-munlockall |
|
| 258 |
-munmap // (*) |
|
| 259 |
-remap_file_pages |
|
| 260 |
-set_mempolicy |
|
| 261 |
-vmsplice |
|
| 262 |
- |
|
| 263 |
-// Process control |
|
| 264 |
-capget |
|
| 265 |
-capset // (*) |
|
| 266 |
-clone // (*) |
|
| 267 |
-execve // (*) |
|
| 268 |
-exit // (*) |
|
| 269 |
-exit_group // (*) |
|
| 270 |
-fork |
|
| 271 |
-getcpu |
|
| 272 |
-getpgid |
|
| 273 |
-getpgrp // (*) |
|
| 274 |
-getpid // (*) |
|
| 275 |
-getppid // (*) |
|
| 276 |
-getpriority |
|
| 277 |
-getresgid |
|
| 278 |
-getresgid32 |
|
| 279 |
-getresuid |
|
| 280 |
-getresuid32 |
|
| 281 |
-getrlimit // (*) |
|
| 282 |
-getrusage |
|
| 283 |
-getsid |
|
| 284 |
-getuid // (*) |
|
| 285 |
-getuid32 |
|
| 286 |
-getegid // (*) |
|
| 287 |
-getegid32 |
|
| 288 |
-geteuid // (*) |
|
| 289 |
-geteuid32 |
|
| 290 |
-getgid // (*) |
|
| 291 |
-getgid32 |
|
| 292 |
-getgroups |
|
| 293 |
-getgroups32 |
|
| 294 |
-getitimer |
|
| 295 |
-get_mempolicy |
|
| 296 |
-kill |
|
| 297 |
-//personality |
|
| 298 |
-prctl |
|
| 299 |
-prlimit64 |
|
| 300 |
-sched_getaffinity |
|
| 301 |
-sched_getparam |
|
| 302 |
-sched_get_priority_max |
|
| 303 |
-sched_get_priority_min |
|
| 304 |
-sched_getscheduler |
|
| 305 |
-sched_rr_get_interval |
|
| 306 |
-//sched_setaffinity |
|
| 307 |
-//sched_setparam |
|
| 308 |
-//sched_setscheduler |
|
| 309 |
-sched_yield |
|
| 310 |
-setfsgid |
|
| 311 |
-setfsgid32 |
|
| 312 |
-setfsuid |
|
| 313 |
-setfsuid32 |
|
| 314 |
-setgid |
|
| 315 |
-setgid32 |
|
| 316 |
-setgroups |
|
| 317 |
-setgroups32 |
|
| 318 |
-setitimer |
|
| 319 |
-setpgid // (*) |
|
| 320 |
-setpriority |
|
| 321 |
-setregid |
|
| 322 |
-setregid32 |
|
| 323 |
-setresgid |
|
| 324 |
-setresgid32 |
|
| 325 |
-setresuid |
|
| 326 |
-setresuid32 |
|
| 327 |
-setreuid |
|
| 328 |
-setreuid32 |
|
| 329 |
-setrlimit |
|
| 330 |
-setsid |
|
| 331 |
-setuid |
|
| 332 |
-setuid32 |
|
| 333 |
-ugetrlimit |
|
| 334 |
-vfork |
|
| 335 |
-wait4 // (*) |
|
| 336 |
-waitid |
|
| 337 |
-waitpid |
|
| 338 |
- |
|
| 339 |
-// IPC |
|
| 340 |
-ipc |
|
| 341 |
-mq_getsetattr |
|
| 342 |
-mq_notify |
|
| 343 |
-mq_open |
|
| 344 |
-mq_timedreceive |
|
| 345 |
-mq_timedsend |
|
| 346 |
-mq_unlink |
|
| 347 |
-msgctl |
|
| 348 |
-msgget |
|
| 349 |
-msgrcv |
|
| 350 |
-msgsnd |
|
| 351 |
-semctl |
|
| 352 |
-semget |
|
| 353 |
-semop |
|
| 354 |
-semtimedop |
|
| 355 |
-shmat |
|
| 356 |
-shmctl |
|
| 357 |
-shmdt |
|
| 358 |
-shmget |
|
| 359 |
- |
|
| 360 |
-// Linux specific, mostly needed for thread-related stuff |
|
| 361 |
-arch_prctl // (*) |
|
| 362 |
-get_robust_list |
|
| 363 |
-get_thread_area |
|
| 364 |
-gettid |
|
| 365 |
-futex // (*) |
|
| 366 |
-restart_syscall // (*) |
|
| 367 |
-set_robust_list // (*) |
|
| 368 |
-set_thread_area |
|
| 369 |
-set_tid_address // (*) |
|
| 370 |
-tgkill |
|
| 371 |
-tkill |
|
| 372 |
- |
|
| 373 |
-// Admin syscalls, these are blocked |
|
| 374 |
-//acct |
|
| 375 |
-//adjtimex |
|
| 376 |
-//bdflush |
|
| 377 |
-//chroot |
|
| 378 |
-//create_module |
|
| 379 |
-//delete_module |
|
| 380 |
-//get_kernel_syms // Obsolete |
|
| 381 |
-//idle // Obsolete |
|
| 382 |
-//init_module |
|
| 383 |
-//ioperm |
|
| 384 |
-//iopl |
|
| 385 |
-//ioprio_get |
|
| 386 |
-//ioprio_set |
|
| 387 |
-//kexec_load |
|
| 388 |
-//lookup_dcookie // oprofile only? |
|
| 389 |
-//migrate_pages // NUMA |
|
| 390 |
-//modify_ldt |
|
| 391 |
-//mount |
|
| 392 |
-//move_pages // NUMA |
|
| 393 |
-//name_to_handle_at // NFS server |
|
| 394 |
-//nfsservctl // NFS server |
|
| 395 |
-//open_by_handle_at // NFS server |
|
| 396 |
-//perf_event_open |
|
| 397 |
-//pivot_root |
|
| 398 |
-//process_vm_readv // For debugger |
|
| 399 |
-//process_vm_writev // For debugger |
|
| 400 |
-//ptrace // For debugger |
|
| 401 |
-//query_module |
|
| 402 |
-//quotactl |
|
| 403 |
-//reboot |
|
| 404 |
-//setdomainname |
|
| 405 |
-//setns |
|
| 406 |
-//settimeofday |
|
| 407 |
-//sgetmask // Obsolete |
|
| 408 |
-//ssetmask // Obsolete |
|
| 409 |
-//stime |
|
| 410 |
-//swapoff |
|
| 411 |
-//swapon |
|
| 412 |
-//_sysctl |
|
| 413 |
-//sysfs |
|
| 414 |
-//sys_setaltroot |
|
| 415 |
-//umount |
|
| 416 |
-//umount2 |
|
| 417 |
-//unshare |
|
| 418 |
-//uselib |
|
| 419 |
-//vhangup |
|
| 420 |
-//vm86 |
|
| 421 |
-//vm86old |
|
| 422 |
- |
|
| 423 |
-// Kernel key management |
|
| 424 |
-//add_key |
|
| 425 |
-//keyctl |
|
| 426 |
-//request_key |
|
| 427 |
- |
|
| 428 |
-// Unimplemented |
|
| 429 |
-//afs_syscall |
|
| 430 |
-//break |
|
| 431 |
-//ftime |
|
| 432 |
-//getpmsg |
|
| 433 |
-//gtty |
|
| 434 |
-//lock |
|
| 435 |
-//madvise1 |
|
| 436 |
-//mpx |
|
| 437 |
-//prof |
|
| 438 |
-//profil |
|
| 439 |
-//putpmsg |
|
| 440 |
-//security |
|
| 441 |
-//stty |
|
| 442 |
-//tuxcall |
|
| 443 |
-//ulimit |
|
| 444 |
-//vserver |
| ... | ... |
@@ -21,7 +21,6 @@ type CommonConfig struct {
|
| 21 | 21 |
DNS []string |
| 22 | 22 |
DNSOptions []string |
| 23 | 23 |
DNSSearch []string |
| 24 |
- ExecDriver string |
|
| 25 | 24 |
ExecOptions []string |
| 26 | 25 |
ExecRoot string |
| 27 | 26 |
GraphDriver string |
| ... | ... |
@@ -62,7 +61,6 @@ func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string) |
| 62 | 62 |
cmd.StringVar(&config.ExecRoot, []string{"-exec-root"}, "/var/run/docker", usageFn("Root of the Docker execdriver"))
|
| 63 | 63 |
cmd.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, usageFn("--restart on the daemon has been deprecated in favor of --restart policies on docker run"))
|
| 64 | 64 |
cmd.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", usageFn("Storage driver to use"))
|
| 65 |
- cmd.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, defaultExec, usageFn("Exec driver to use"))
|
|
| 66 | 65 |
cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU"))
|
| 67 | 66 |
// FIXME: why the inconsistency between "hosts" and "sockets"? |
| 68 | 67 |
cmd.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use"))
|
| ... | ... |
@@ -63,7 +63,6 @@ type CommonContainer struct {
|
| 63 | 63 |
LogPath string |
| 64 | 64 |
Name string |
| 65 | 65 |
Driver string |
| 66 |
- ExecDriver string |
|
| 67 | 66 |
// MountLabel contains the options for the 'mount' command |
| 68 | 67 |
MountLabel string |
| 69 | 68 |
ProcessLabel string |
| ... | ... |
@@ -258,7 +257,6 @@ func (container *Container) jsonPath() (string, error) {
|
| 258 | 258 |
return container.getRootResourcePath("config.json")
|
| 259 | 259 |
} |
| 260 | 260 |
|
| 261 |
-// This method must be exported to be used from the lxc template |
|
| 262 | 261 |
// This directory is only usable when the container is running |
| 263 | 262 |
func (container *Container) rootfsPath() string {
|
| 264 | 263 |
return container.basefs |
| ... | ... |
@@ -255,12 +255,6 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
|
| 255 | 255 |
|
| 256 | 256 |
autoCreatedDevices := mergeDevices(configs.DefaultAutoCreatedDevices, userSpecifiedDevices) |
| 257 | 257 |
|
| 258 |
- // TODO: this can be removed after lxc-conf is fully deprecated |
|
| 259 |
- lxcConfig, err := mergeLxcConfIntoOptions(c.hostConfig) |
|
| 260 |
- if err != nil {
|
|
| 261 |
- return err |
|
| 262 |
- } |
|
| 263 |
- |
|
| 264 | 258 |
var rlimits []*ulimit.Rlimit |
| 265 | 259 |
ulimits := c.hostConfig.Ulimits |
| 266 | 260 |
|
| ... | ... |
@@ -345,7 +339,6 @@ func (daemon *Daemon) populateCommand(c *Container, env []string) error {
|
| 345 | 345 |
GIDMapping: gidMap, |
| 346 | 346 |
GroupAdd: c.hostConfig.GroupAdd, |
| 347 | 347 |
Ipc: ipc, |
| 348 |
- LxcConfig: lxcConfig, |
|
| 349 | 348 |
Pid: pid, |
| 350 | 349 |
ReadonlyRootfs: c.hostConfig.ReadonlyRootfs, |
| 351 | 350 |
RemappedRoot: remappedRoot, |
| ... | ... |
@@ -451,7 +451,6 @@ func (daemon *Daemon) generateNewName(id string) (string, error) {
|
| 451 | 451 |
|
| 452 | 452 |
func (daemon *Daemon) generateHostname(id string, config *runconfig.Config) {
|
| 453 | 453 |
// Generate default hostname |
| 454 |
- // FIXME: the lxc template no longer needs to set a default hostname |
|
| 455 | 454 |
if config.Hostname == "" {
|
| 456 | 455 |
config.Hostname = id[:12] |
| 457 | 456 |
} |
| ... | ... |
@@ -490,7 +489,6 @@ func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID |
| 490 | 490 |
base.NetworkSettings = &network.Settings{IsAnonymousEndpoint: noExplicitName}
|
| 491 | 491 |
base.Name = name |
| 492 | 492 |
base.Driver = daemon.driver.String() |
| 493 |
- base.ExecDriver = daemon.execDriver.Name() |
|
| 494 | 493 |
|
| 495 | 494 |
return base, err |
| 496 | 495 |
} |
| ... | ... |
@@ -786,13 +784,6 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo |
| 786 | 786 |
d.containerGraphDB = graph |
| 787 | 787 |
|
| 788 | 788 |
var sysInitPath string |
| 789 |
- if config.ExecDriver == "lxc" {
|
|
| 790 |
- initPath, err := configureSysInit(config, rootUID, rootGID) |
|
| 791 |
- if err != nil {
|
|
| 792 |
- return nil, err |
|
| 793 |
- } |
|
| 794 |
- sysInitPath = initPath |
|
| 795 |
- } |
|
| 796 | 789 |
|
| 797 | 790 |
sysInfo := sysinfo.New(false) |
| 798 | 791 |
// Check if Devices cgroup is mounted, it is hard requirement for container security, |
| ... | ... |
@@ -801,7 +792,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo |
| 801 | 801 |
return nil, fmt.Errorf("Devices cgroup isn't mounted")
|
| 802 | 802 |
} |
| 803 | 803 |
|
| 804 |
- ed, err := execdrivers.NewDriver(config.ExecDriver, config.ExecOptions, config.ExecRoot, config.Root, sysInitPath, sysInfo) |
|
| 804 |
+ ed, err := execdrivers.NewDriver(config.ExecOptions, config.ExecRoot, config.Root, sysInitPath, sysInfo) |
|
| 805 | 805 |
if err != nil {
|
| 806 | 806 |
return nil, err |
| 807 | 807 |
} |
| ... | ... |
@@ -15,11 +15,8 @@ import ( |
| 15 | 15 |
) |
| 16 | 16 |
|
| 17 | 17 |
func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) {
|
| 18 |
- if config.ExecDriver != "native" && config.RemappedRoot != "" {
|
|
| 19 |
- return nil, nil, fmt.Errorf("User namespace remapping is only supported with the native execdriver")
|
|
| 20 |
- } |
|
| 21 |
- if runtime.GOOS == "windows" && config.RemappedRoot != "" {
|
|
| 22 |
- return nil, nil, fmt.Errorf("User namespaces are not supported on Windows")
|
|
| 18 |
+ if runtime.GOOS != "linux" && config.RemappedRoot != "" {
|
|
| 19 |
+ return nil, nil, fmt.Errorf("User namespaces are not supported on Linux")
|
|
| 23 | 20 |
} |
| 24 | 21 |
|
| 25 | 22 |
// if the daemon was started with remapped root option, parse |
| ... | ... |
@@ -166,7 +166,7 @@ func TestLoadWithVolume(t *testing.T) {
|
| 166 | 166 |
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname", |
| 167 | 167 |
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts", |
| 168 | 168 |
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log", |
| 169 |
-"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 169 |
+"Name":"/ubuntu","Driver":"aufs","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 170 | 170 |
"UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
|
| 171 | 171 |
|
| 172 | 172 |
cfg := fmt.Sprintf(config, vfsPath) |
| ... | ... |
@@ -255,7 +255,7 @@ func TestLoadWithBindMount(t *testing.T) {
|
| 255 | 255 |
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname", |
| 256 | 256 |
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts", |
| 257 | 257 |
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log", |
| 258 |
-"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 258 |
+"Name":"/ubuntu","Driver":"aufs","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 259 | 259 |
"UpdateDns":false,"Volumes":{"/vol1": "/vol1"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
|
| 260 | 260 |
|
| 261 | 261 |
if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(config), 0644); err != nil {
|
| ... | ... |
@@ -346,7 +346,7 @@ func TestLoadWithVolume17RC(t *testing.T) {
|
| 346 | 346 |
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname", |
| 347 | 347 |
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts", |
| 348 | 348 |
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log", |
| 349 |
-"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 349 |
+"Name":"/ubuntu","Driver":"aufs","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 350 | 350 |
"UpdateDns":false,"MountPoints":{"/vol1":{"Name":"6a3c03fc4a4e588561a543cc3bdd50089e27bd11bbb0e551e19bf735e2514101","Destination":"/vol1","Driver":"local","RW":true,"Source":"","Relabel":""}},"AppliedVolumesFrom":null}`
|
| 351 | 351 |
|
| 352 | 352 |
if err = ioutil.WriteFile(filepath.Join(containerPath, "config.json"), []byte(config), 0644); err != nil {
|
| ... | ... |
@@ -450,7 +450,7 @@ func TestRemoveLocalVolumesFollowingSymlinks(t *testing.T) {
|
| 450 | 450 |
"HostnamePath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hostname", |
| 451 | 451 |
"HostsPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/hosts", |
| 452 | 452 |
"LogPath":"/var/lib/docker/containers/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e/d59df5276e7b219d510fe70565e0404bc06350e0d4b43fe961f22f339980170e-json.log", |
| 453 |
-"Name":"/ubuntu","Driver":"aufs","ExecDriver":"native-0.2","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 453 |
+"Name":"/ubuntu","Driver":"aufs","MountLabel":"","ProcessLabel":"","AppArmorProfile":"","RestartCount":0, |
|
| 454 | 454 |
"UpdateDns":false,"Volumes":{"/vol1":"%s"},"VolumesRW":{"/vol1":true},"AppliedVolumesFrom":null}`
|
| 455 | 455 |
|
| 456 | 456 |
cfg := fmt.Sprintf(config, vfsPath) |
| ... | ... |
@@ -128,10 +128,6 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *runconfig.HostC |
| 128 | 128 |
return warnings, err |
| 129 | 129 |
} |
| 130 | 130 |
|
| 131 |
- if hostConfig.LxcConf.Len() > 0 && !strings.Contains(daemon.ExecutionDriver().Name(), "lxc") {
|
|
| 132 |
- return warnings, fmt.Errorf("Cannot use --lxc-conf with execdriver: %s", daemon.ExecutionDriver().Name())
|
|
| 133 |
- } |
|
| 134 |
- |
|
| 135 | 131 |
// memory subsystem checks and adjustments |
| 136 | 132 |
if hostConfig.Memory != 0 && hostConfig.Memory < 4194304 {
|
| 137 | 133 |
return warnings, fmt.Errorf("Minimum memory limit allowed is 4MB")
|
| ... | ... |
@@ -148,11 +148,6 @@ func (d *Daemon) getActiveContainer(name string) (*Container, error) {
|
| 148 | 148 |
|
| 149 | 149 |
// ContainerExecCreate sets up an exec in a running container. |
| 150 | 150 |
func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, error) {
|
| 151 |
- // Not all drivers support Exec (LXC for example) |
|
| 152 |
- if err := checkExecSupport(d.execDriver.Name()); err != nil {
|
|
| 153 |
- return "", err |
|
| 154 |
- } |
|
| 155 |
- |
|
| 156 | 151 |
container, err := d.getActiveContainer(config.Container) |
| 157 | 152 |
if err != nil {
|
| 158 | 153 |
return "", err |
| 10 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,18 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package daemon |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "strings" |
|
| 7 |
- |
|
| 8 |
- "github.com/docker/docker/daemon/execdriver/lxc" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-// checkExecSupport returns an error if the exec driver does not support exec, |
|
| 12 |
-// or nil if it is supported. |
|
| 13 |
-func checkExecSupport(drivername string) error {
|
|
| 14 |
- if strings.HasPrefix(drivername, lxc.DriverName) {
|
|
| 15 |
- return lxc.ErrExec |
|
| 16 |
- } |
|
| 17 |
- return nil |
|
| 18 |
-} |
| ... | ... |
@@ -100,7 +100,6 @@ type Command struct {
|
| 100 | 100 |
GIDMapping []idtools.IDMap `json:"gidmapping"` |
| 101 | 101 |
GroupAdd []string `json:"group_add"` |
| 102 | 102 |
Ipc *Ipc `json:"ipc"` |
| 103 |
- LxcConfig []string `json:"lxc_config"` |
|
| 104 | 103 |
Pid *Pid `json:"pid"` |
| 105 | 104 |
ReadonlyRootfs bool `json:"readonly_rootfs"` |
| 106 | 105 |
RemappedRoot *User `json:"remap_root"` |
| ... | ... |
@@ -10,10 +10,6 @@ import ( |
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 | 12 |
// NewDriver returns a new execdriver.Driver from the given name configured with the provided options. |
| 13 |
-func NewDriver(name string, options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
|
|
| 14 |
- switch name {
|
|
| 15 |
- case "jail": |
|
| 16 |
- return nil, fmt.Errorf("jail driver not yet supported on FreeBSD")
|
|
| 17 |
- } |
|
| 18 |
- return nil, fmt.Errorf("unknown exec driver %s", name)
|
|
| 13 |
+func NewDriver(options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
|
|
| 14 |
+ return nil, fmt.Errorf("jail driver not yet supported on FreeBSD")
|
|
| 19 | 15 |
} |
| ... | ... |
@@ -3,27 +3,14 @@ |
| 3 | 3 |
package execdrivers |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
- "fmt" |
|
| 7 | 6 |
"path" |
| 8 | 7 |
|
| 9 |
- "github.com/Sirupsen/logrus" |
|
| 10 | 8 |
"github.com/docker/docker/daemon/execdriver" |
| 11 |
- "github.com/docker/docker/daemon/execdriver/lxc" |
|
| 12 | 9 |
"github.com/docker/docker/daemon/execdriver/native" |
| 13 | 10 |
"github.com/docker/docker/pkg/sysinfo" |
| 14 | 11 |
) |
| 15 | 12 |
|
| 16 | 13 |
// NewDriver returns a new execdriver.Driver from the given name configured with the provided options. |
| 17 |
-func NewDriver(name string, options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
|
|
| 18 |
- switch name {
|
|
| 19 |
- case "lxc": |
|
| 20 |
- // we want to give the lxc driver the full docker root because it needs |
|
| 21 |
- // to access and write config and template files in /var/lib/docker/containers/* |
|
| 22 |
- // to be backwards compatible |
|
| 23 |
- logrus.Warn("LXC built-in support is deprecated.")
|
|
| 24 |
- return lxc.NewDriver(root, libPath, initPath, sysInfo.AppArmor) |
|
| 25 |
- case "native": |
|
| 26 |
- return native.NewDriver(path.Join(root, "execdriver", "native"), initPath, options) |
|
| 27 |
- } |
|
| 28 |
- return nil, fmt.Errorf("unknown exec driver %s", name)
|
|
| 14 |
+func NewDriver(options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
|
|
| 15 |
+ return native.NewDriver(path.Join(root, "execdriver", "native"), initPath, options) |
|
| 29 | 16 |
} |
| ... | ... |
@@ -3,18 +3,12 @@ |
| 3 | 3 |
package execdrivers |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
- "fmt" |
|
| 7 |
- |
|
| 8 | 6 |
"github.com/docker/docker/daemon/execdriver" |
| 9 | 7 |
"github.com/docker/docker/daemon/execdriver/windows" |
| 10 | 8 |
"github.com/docker/docker/pkg/sysinfo" |
| 11 | 9 |
) |
| 12 | 10 |
|
| 13 | 11 |
// NewDriver returns a new execdriver.Driver from the given name configured with the provided options. |
| 14 |
-func NewDriver(name string, options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
|
|
| 15 |
- switch name {
|
|
| 16 |
- case "windows": |
|
| 17 |
- return windows.NewDriver(root, initPath, options) |
|
| 18 |
- } |
|
| 19 |
- return nil, fmt.Errorf("unknown exec driver %s", name)
|
|
| 12 |
+func NewDriver(options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
|
|
| 13 |
+ return windows.NewDriver(root, initPath, options) |
|
| 20 | 14 |
} |
| 21 | 15 |
deleted file mode 100644 |
| ... | ... |
@@ -1,906 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "encoding/json" |
|
| 7 |
- "errors" |
|
| 8 |
- "fmt" |
|
| 9 |
- "io" |
|
| 10 |
- "io/ioutil" |
|
| 11 |
- "os" |
|
| 12 |
- "os/exec" |
|
| 13 |
- "path" |
|
| 14 |
- "path/filepath" |
|
| 15 |
- "runtime" |
|
| 16 |
- "strconv" |
|
| 17 |
- "strings" |
|
| 18 |
- "sync" |
|
| 19 |
- "syscall" |
|
| 20 |
- "time" |
|
| 21 |
- |
|
| 22 |
- "github.com/Sirupsen/logrus" |
|
| 23 |
- "github.com/docker/docker/daemon/execdriver" |
|
| 24 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 25 |
- sysinfo "github.com/docker/docker/pkg/system" |
|
| 26 |
- "github.com/docker/docker/pkg/term" |
|
| 27 |
- "github.com/docker/docker/pkg/version" |
|
| 28 |
- "github.com/kr/pty" |
|
| 29 |
- "github.com/opencontainers/runc/libcontainer" |
|
| 30 |
- "github.com/opencontainers/runc/libcontainer/cgroups" |
|
| 31 |
- "github.com/opencontainers/runc/libcontainer/configs" |
|
| 32 |
- "github.com/opencontainers/runc/libcontainer/system" |
|
| 33 |
- "github.com/opencontainers/runc/libcontainer/user" |
|
| 34 |
- "github.com/vishvananda/netns" |
|
| 35 |
-) |
|
| 36 |
- |
|
| 37 |
-// DriverName for lxc driver |
|
| 38 |
-const DriverName = "lxc" |
|
| 39 |
- |
|
| 40 |
-// ErrExec defines unsupported error message |
|
| 41 |
-var ErrExec = errors.New("Unsupported: Exec is not supported by the lxc driver")
|
|
| 42 |
- |
|
| 43 |
-// Driver contains all information for lxc driver, |
|
| 44 |
-// it implements execdriver.Driver |
|
| 45 |
-type Driver struct {
|
|
| 46 |
- root string // root path for the driver to use |
|
| 47 |
- libPath string |
|
| 48 |
- initPath string |
|
| 49 |
- apparmor bool |
|
| 50 |
- sharedRoot bool |
|
| 51 |
- activeContainers map[string]*activeContainer |
|
| 52 |
- machineMemory int64 |
|
| 53 |
- sync.Mutex |
|
| 54 |
-} |
|
| 55 |
- |
|
| 56 |
-type activeContainer struct {
|
|
| 57 |
- container *configs.Config |
|
| 58 |
- cmd *exec.Cmd |
|
| 59 |
-} |
|
| 60 |
- |
|
| 61 |
-// NewDriver returns a new lxc driver, called from NewDriver of execdriver |
|
| 62 |
-func NewDriver(root, libPath, initPath string, apparmor bool) (*Driver, error) {
|
|
| 63 |
- if err := os.MkdirAll(root, 0700); err != nil {
|
|
| 64 |
- return nil, err |
|
| 65 |
- } |
|
| 66 |
- // setup unconfined symlink |
|
| 67 |
- if err := linkLxcStart(root); err != nil {
|
|
| 68 |
- return nil, err |
|
| 69 |
- } |
|
| 70 |
- meminfo, err := sysinfo.ReadMemInfo() |
|
| 71 |
- if err != nil {
|
|
| 72 |
- return nil, err |
|
| 73 |
- } |
|
| 74 |
- return &Driver{
|
|
| 75 |
- apparmor: apparmor, |
|
| 76 |
- root: root, |
|
| 77 |
- libPath: libPath, |
|
| 78 |
- initPath: initPath, |
|
| 79 |
- sharedRoot: rootIsShared(), |
|
| 80 |
- activeContainers: make(map[string]*activeContainer), |
|
| 81 |
- machineMemory: meminfo.MemTotal, |
|
| 82 |
- }, nil |
|
| 83 |
-} |
|
| 84 |
- |
|
| 85 |
-// Name implements the exec driver Driver interface. |
|
| 86 |
-func (d *Driver) Name() string {
|
|
| 87 |
- version := d.version() |
|
| 88 |
- return fmt.Sprintf("%s-%s", DriverName, version)
|
|
| 89 |
-} |
|
| 90 |
- |
|
| 91 |
-func setupNetNs(nsPath string) (*os.Process, error) {
|
|
| 92 |
- runtime.LockOSThread() |
|
| 93 |
- defer runtime.UnlockOSThread() |
|
| 94 |
- |
|
| 95 |
- origns, err := netns.Get() |
|
| 96 |
- if err != nil {
|
|
| 97 |
- return nil, err |
|
| 98 |
- } |
|
| 99 |
- defer origns.Close() |
|
| 100 |
- |
|
| 101 |
- f, err := os.OpenFile(nsPath, os.O_RDONLY, 0) |
|
| 102 |
- if err != nil {
|
|
| 103 |
- return nil, fmt.Errorf("failed to get network namespace %q: %v", nsPath, err)
|
|
| 104 |
- } |
|
| 105 |
- defer f.Close() |
|
| 106 |
- |
|
| 107 |
- nsFD := f.Fd() |
|
| 108 |
- if err := netns.Set(netns.NsHandle(nsFD)); err != nil {
|
|
| 109 |
- return nil, fmt.Errorf("failed to set network namespace %q: %v", nsPath, err)
|
|
| 110 |
- } |
|
| 111 |
- defer netns.Set(origns) |
|
| 112 |
- |
|
| 113 |
- cmd := exec.Command("/bin/sh", "-c", "while true; do sleep 1; done")
|
|
| 114 |
- if err := cmd.Start(); err != nil {
|
|
| 115 |
- return nil, fmt.Errorf("failed to start netns process: %v", err)
|
|
| 116 |
- } |
|
| 117 |
- |
|
| 118 |
- return cmd.Process, nil |
|
| 119 |
-} |
|
| 120 |
- |
|
| 121 |
-func killNetNsProc(proc *os.Process) {
|
|
| 122 |
- proc.Kill() |
|
| 123 |
- proc.Wait() |
|
| 124 |
-} |
|
| 125 |
- |
|
| 126 |
-// Run implements the exec driver Driver interface, |
|
| 127 |
-// it calls 'exec.Cmd' to launch lxc commands to run a container. |
|
| 128 |
-func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execdriver.Hooks) (execdriver.ExitStatus, error) {
|
|
| 129 |
- var ( |
|
| 130 |
- term execdriver.Terminal |
|
| 131 |
- err error |
|
| 132 |
- dataPath = d.containerDir(c.ID) |
|
| 133 |
- ) |
|
| 134 |
- |
|
| 135 |
- if c.Network == nil || (c.Network.NamespacePath == "" && c.Network.ContainerID == "") {
|
|
| 136 |
- return execdriver.ExitStatus{ExitCode: -1}, fmt.Errorf("empty namespace path for non-container network")
|
|
| 137 |
- } |
|
| 138 |
- |
|
| 139 |
- container, err := d.createContainer(c) |
|
| 140 |
- if err != nil {
|
|
| 141 |
- return execdriver.ExitStatus{ExitCode: -1}, err
|
|
| 142 |
- } |
|
| 143 |
- |
|
| 144 |
- if c.ProcessConfig.Tty {
|
|
| 145 |
- term, err = NewTtyConsole(&c.ProcessConfig, pipes) |
|
| 146 |
- } else {
|
|
| 147 |
- term, err = execdriver.NewStdConsole(&c.ProcessConfig, pipes) |
|
| 148 |
- } |
|
| 149 |
- if err != nil {
|
|
| 150 |
- return execdriver.ExitStatus{ExitCode: -1}, err
|
|
| 151 |
- } |
|
| 152 |
- c.ProcessConfig.Terminal = term |
|
| 153 |
- |
|
| 154 |
- d.Lock() |
|
| 155 |
- d.activeContainers[c.ID] = &activeContainer{
|
|
| 156 |
- container: container, |
|
| 157 |
- cmd: &c.ProcessConfig.Cmd, |
|
| 158 |
- } |
|
| 159 |
- d.Unlock() |
|
| 160 |
- |
|
| 161 |
- c.Mounts = append(c.Mounts, execdriver.Mount{
|
|
| 162 |
- Source: d.initPath, |
|
| 163 |
- Destination: c.InitPath, |
|
| 164 |
- Writable: false, |
|
| 165 |
- Private: true, |
|
| 166 |
- }) |
|
| 167 |
- |
|
| 168 |
- if err := d.generateEnvConfig(c); err != nil {
|
|
| 169 |
- return execdriver.ExitStatus{ExitCode: -1}, err
|
|
| 170 |
- } |
|
| 171 |
- configPath, err := d.generateLXCConfig(c) |
|
| 172 |
- if err != nil {
|
|
| 173 |
- return execdriver.ExitStatus{ExitCode: -1}, err
|
|
| 174 |
- } |
|
| 175 |
- params := []string{
|
|
| 176 |
- "lxc-start", |
|
| 177 |
- "-n", c.ID, |
|
| 178 |
- "-f", configPath, |
|
| 179 |
- "-q", |
|
| 180 |
- } |
|
| 181 |
- |
|
| 182 |
- // From lxc>=1.1 the default behavior is to daemonize containers after start |
|
| 183 |
- lxcVersion := version.Version(d.version()) |
|
| 184 |
- if lxcVersion.GreaterThanOrEqualTo(version.Version("1.1")) {
|
|
| 185 |
- params = append(params, "-F") |
|
| 186 |
- } |
|
| 187 |
- |
|
| 188 |
- proc := &os.Process{}
|
|
| 189 |
- if c.Network.ContainerID != "" {
|
|
| 190 |
- params = append(params, |
|
| 191 |
- "--share-net", c.Network.ContainerID, |
|
| 192 |
- ) |
|
| 193 |
- } else {
|
|
| 194 |
- proc, err = setupNetNs(c.Network.NamespacePath) |
|
| 195 |
- if err != nil {
|
|
| 196 |
- return execdriver.ExitStatus{ExitCode: -1}, err
|
|
| 197 |
- } |
|
| 198 |
- |
|
| 199 |
- pidStr := fmt.Sprintf("%d", proc.Pid)
|
|
| 200 |
- params = append(params, |
|
| 201 |
- "--share-net", pidStr) |
|
| 202 |
- } |
|
| 203 |
- if c.Ipc != nil {
|
|
| 204 |
- if c.Ipc.ContainerID != "" {
|
|
| 205 |
- params = append(params, |
|
| 206 |
- "--share-ipc", c.Ipc.ContainerID, |
|
| 207 |
- ) |
|
| 208 |
- } else if c.Ipc.HostIpc {
|
|
| 209 |
- params = append(params, |
|
| 210 |
- "--share-ipc", "1", |
|
| 211 |
- ) |
|
| 212 |
- } |
|
| 213 |
- } |
|
| 214 |
- |
|
| 215 |
- params = append(params, |
|
| 216 |
- "--", |
|
| 217 |
- c.InitPath, |
|
| 218 |
- ) |
|
| 219 |
- |
|
| 220 |
- if c.ProcessConfig.User != "" {
|
|
| 221 |
- params = append(params, "-u", c.ProcessConfig.User) |
|
| 222 |
- } |
|
| 223 |
- |
|
| 224 |
- if c.ProcessConfig.Privileged {
|
|
| 225 |
- if d.apparmor {
|
|
| 226 |
- params[0] = path.Join(d.root, "lxc-start-unconfined") |
|
| 227 |
- |
|
| 228 |
- } |
|
| 229 |
- params = append(params, "-privileged") |
|
| 230 |
- } |
|
| 231 |
- |
|
| 232 |
- if c.WorkingDir != "" {
|
|
| 233 |
- params = append(params, "-w", c.WorkingDir) |
|
| 234 |
- } |
|
| 235 |
- |
|
| 236 |
- params = append(params, "--", c.ProcessConfig.Entrypoint) |
|
| 237 |
- params = append(params, c.ProcessConfig.Arguments...) |
|
| 238 |
- |
|
| 239 |
- if d.sharedRoot {
|
|
| 240 |
- // lxc-start really needs / to be non-shared, or all kinds of stuff break |
|
| 241 |
- // when lxc-start unmount things and those unmounts propagate to the main |
|
| 242 |
- // mount namespace. |
|
| 243 |
- // What we really want is to clone into a new namespace and then |
|
| 244 |
- // mount / MS_REC|MS_SLAVE, but since we can't really clone or fork |
|
| 245 |
- // without exec in go we have to do this horrible shell hack... |
|
| 246 |
- shellString := |
|
| 247 |
- "mount --make-rslave /; exec " + |
|
| 248 |
- stringutils.ShellQuoteArguments(params) |
|
| 249 |
- |
|
| 250 |
- params = []string{
|
|
| 251 |
- "unshare", "-m", "--", "/bin/sh", "-c", shellString, |
|
| 252 |
- } |
|
| 253 |
- } |
|
| 254 |
- logrus.Debugf("lxc params %s", params)
|
|
| 255 |
- var ( |
|
| 256 |
- name = params[0] |
|
| 257 |
- arg = params[1:] |
|
| 258 |
- ) |
|
| 259 |
- aname, err := exec.LookPath(name) |
|
| 260 |
- if err != nil {
|
|
| 261 |
- aname = name |
|
| 262 |
- } |
|
| 263 |
- c.ProcessConfig.Path = aname |
|
| 264 |
- c.ProcessConfig.Args = append([]string{name}, arg...)
|
|
| 265 |
- |
|
| 266 |
- if err := createDeviceNodes(c.Rootfs, c.AutoCreatedDevices); err != nil {
|
|
| 267 |
- killNetNsProc(proc) |
|
| 268 |
- return execdriver.ExitStatus{ExitCode: -1}, err
|
|
| 269 |
- } |
|
| 270 |
- |
|
| 271 |
- if err := c.ProcessConfig.Start(); err != nil {
|
|
| 272 |
- killNetNsProc(proc) |
|
| 273 |
- return execdriver.ExitStatus{ExitCode: -1}, err
|
|
| 274 |
- } |
|
| 275 |
- |
|
| 276 |
- var ( |
|
| 277 |
- waitErr error |
|
| 278 |
- waitLock = make(chan struct{})
|
|
| 279 |
- ) |
|
| 280 |
- |
|
| 281 |
- go func() {
|
|
| 282 |
- if err := c.ProcessConfig.Wait(); err != nil {
|
|
| 283 |
- if _, ok := err.(*exec.ExitError); !ok { // Do not propagate the error if it's simply a status code != 0
|
|
| 284 |
- waitErr = err |
|
| 285 |
- } |
|
| 286 |
- } |
|
| 287 |
- close(waitLock) |
|
| 288 |
- }() |
|
| 289 |
- |
|
| 290 |
- terminate := func(terr error) (execdriver.ExitStatus, error) {
|
|
| 291 |
- if c.ProcessConfig.Process != nil {
|
|
| 292 |
- c.ProcessConfig.Process.Kill() |
|
| 293 |
- c.ProcessConfig.Wait() |
|
| 294 |
- } |
|
| 295 |
- return execdriver.ExitStatus{ExitCode: -1}, terr
|
|
| 296 |
- } |
|
| 297 |
- // Poll lxc for RUNNING status |
|
| 298 |
- pid, err := d.waitForStart(c, waitLock) |
|
| 299 |
- if err != nil {
|
|
| 300 |
- killNetNsProc(proc) |
|
| 301 |
- return terminate(err) |
|
| 302 |
- } |
|
| 303 |
- killNetNsProc(proc) |
|
| 304 |
- |
|
| 305 |
- cgroupPaths, err := cgroupPaths(c.ID) |
|
| 306 |
- if err != nil {
|
|
| 307 |
- return terminate(err) |
|
| 308 |
- } |
|
| 309 |
- |
|
| 310 |
- state := &libcontainer.State{
|
|
| 311 |
- InitProcessPid: pid, |
|
| 312 |
- CgroupPaths: cgroupPaths, |
|
| 313 |
- } |
|
| 314 |
- |
|
| 315 |
- f, err := os.Create(filepath.Join(dataPath, "state.json")) |
|
| 316 |
- if err != nil {
|
|
| 317 |
- return terminate(err) |
|
| 318 |
- } |
|
| 319 |
- defer f.Close() |
|
| 320 |
- |
|
| 321 |
- if err := json.NewEncoder(f).Encode(state); err != nil {
|
|
| 322 |
- return terminate(err) |
|
| 323 |
- } |
|
| 324 |
- |
|
| 325 |
- c.ContainerPid = pid |
|
| 326 |
- |
|
| 327 |
- if hooks.Start != nil {
|
|
| 328 |
- logrus.Debugf("Invoking startCallback")
|
|
| 329 |
- chOOM := make(chan struct{})
|
|
| 330 |
- close(chOOM) |
|
| 331 |
- hooks.Start(&c.ProcessConfig, pid, chOOM) |
|
| 332 |
- } |
|
| 333 |
- |
|
| 334 |
- oomKillNotification := notifyChannelOOM(cgroupPaths) |
|
| 335 |
- |
|
| 336 |
- <-waitLock |
|
| 337 |
- exitCode := getExitCode(c) |
|
| 338 |
- |
|
| 339 |
- _, oomKill := <-oomKillNotification |
|
| 340 |
- logrus.Debugf("oomKill error: %v, waitErr: %v", oomKill, waitErr)
|
|
| 341 |
- |
|
| 342 |
- // check oom error |
|
| 343 |
- if oomKill {
|
|
| 344 |
- exitCode = 137 |
|
| 345 |
- } |
|
| 346 |
- |
|
| 347 |
- return execdriver.ExitStatus{ExitCode: exitCode, OOMKilled: oomKill}, waitErr
|
|
| 348 |
-} |
|
| 349 |
- |
|
| 350 |
-func notifyChannelOOM(paths map[string]string) <-chan struct{} {
|
|
| 351 |
- oom, err := notifyOnOOM(paths) |
|
| 352 |
- if err != nil {
|
|
| 353 |
- logrus.Warnf("Your kernel does not support OOM notifications: %s", err)
|
|
| 354 |
- c := make(chan struct{})
|
|
| 355 |
- close(c) |
|
| 356 |
- return c |
|
| 357 |
- } |
|
| 358 |
- return oom |
|
| 359 |
-} |
|
| 360 |
- |
|
| 361 |
-// copy from libcontainer |
|
| 362 |
-func notifyOnOOM(paths map[string]string) (<-chan struct{}, error) {
|
|
| 363 |
- dir := paths["memory"] |
|
| 364 |
- if dir == "" {
|
|
| 365 |
- return nil, fmt.Errorf("There is no path for %q in state", "memory")
|
|
| 366 |
- } |
|
| 367 |
- oomControl, err := os.Open(filepath.Join(dir, "memory.oom_control")) |
|
| 368 |
- if err != nil {
|
|
| 369 |
- return nil, err |
|
| 370 |
- } |
|
| 371 |
- fd, _, syserr := syscall.RawSyscall(syscall.SYS_EVENTFD2, 0, syscall.FD_CLOEXEC, 0) |
|
| 372 |
- if syserr != 0 {
|
|
| 373 |
- oomControl.Close() |
|
| 374 |
- return nil, syserr |
|
| 375 |
- } |
|
| 376 |
- |
|
| 377 |
- eventfd := os.NewFile(fd, "eventfd") |
|
| 378 |
- |
|
| 379 |
- eventControlPath := filepath.Join(dir, "cgroup.event_control") |
|
| 380 |
- data := fmt.Sprintf("%d %d", eventfd.Fd(), oomControl.Fd())
|
|
| 381 |
- if err := ioutil.WriteFile(eventControlPath, []byte(data), 0700); err != nil {
|
|
| 382 |
- eventfd.Close() |
|
| 383 |
- oomControl.Close() |
|
| 384 |
- return nil, err |
|
| 385 |
- } |
|
| 386 |
- ch := make(chan struct{})
|
|
| 387 |
- go func() {
|
|
| 388 |
- defer func() {
|
|
| 389 |
- close(ch) |
|
| 390 |
- eventfd.Close() |
|
| 391 |
- oomControl.Close() |
|
| 392 |
- }() |
|
| 393 |
- buf := make([]byte, 8) |
|
| 394 |
- for {
|
|
| 395 |
- if _, err := eventfd.Read(buf); err != nil {
|
|
| 396 |
- logrus.Warn(err) |
|
| 397 |
- return |
|
| 398 |
- } |
|
| 399 |
- // When a cgroup is destroyed, an event is sent to eventfd. |
|
| 400 |
- // So if the control path is gone, return instead of notifying. |
|
| 401 |
- if _, err := os.Lstat(eventControlPath); os.IsNotExist(err) {
|
|
| 402 |
- logrus.Warn(err) |
|
| 403 |
- return |
|
| 404 |
- } |
|
| 405 |
- ch <- struct{}{}
|
|
| 406 |
- } |
|
| 407 |
- }() |
|
| 408 |
- return ch, nil |
|
| 409 |
-} |
|
| 410 |
- |
|
| 411 |
-// createContainer populates and configures the container type with the |
|
| 412 |
-// data provided by the execdriver.Command |
|
| 413 |
-func (d *Driver) createContainer(c *execdriver.Command) (*configs.Config, error) {
|
|
| 414 |
- container := execdriver.InitContainer(c) |
|
| 415 |
- if err := execdriver.SetupCgroups(container, c); err != nil {
|
|
| 416 |
- return nil, err |
|
| 417 |
- } |
|
| 418 |
- return container, nil |
|
| 419 |
-} |
|
| 420 |
- |
|
| 421 |
-// Return an map of susbystem -> absolute container cgroup path |
|
| 422 |
-func cgroupPaths(containerID string) (map[string]string, error) {
|
|
| 423 |
- subsystems, err := cgroups.GetAllSubsystems() |
|
| 424 |
- if err != nil {
|
|
| 425 |
- return nil, err |
|
| 426 |
- } |
|
| 427 |
- logrus.Debugf("subsystems: %s", subsystems)
|
|
| 428 |
- paths := make(map[string]string) |
|
| 429 |
- for _, subsystem := range subsystems {
|
|
| 430 |
- cgroupRoot, cgroupDir, err := findCgroupRootAndDir(subsystem) |
|
| 431 |
- logrus.Debugf("cgroup path %s %s", cgroupRoot, cgroupDir)
|
|
| 432 |
- if err != nil {
|
|
| 433 |
- //unsupported subystem |
|
| 434 |
- continue |
|
| 435 |
- } |
|
| 436 |
- // if we are running dind |
|
| 437 |
- dockerPathIdx := strings.LastIndex(cgroupDir, "docker") |
|
| 438 |
- if dockerPathIdx != -1 {
|
|
| 439 |
- cgroupDir = cgroupDir[:dockerPathIdx-1] |
|
| 440 |
- } |
|
| 441 |
- path := filepath.Join(cgroupRoot, cgroupDir, "lxc", containerID) |
|
| 442 |
- paths[subsystem] = path |
|
| 443 |
- } |
|
| 444 |
- |
|
| 445 |
- return paths, nil |
|
| 446 |
-} |
|
| 447 |
- |
|
| 448 |
-// this is copy from old libcontainer nodes.go |
|
| 449 |
-func createDeviceNodes(rootfs string, nodesToCreate []*configs.Device) error {
|
|
| 450 |
- oldMask := syscall.Umask(0000) |
|
| 451 |
- defer syscall.Umask(oldMask) |
|
| 452 |
- |
|
| 453 |
- for _, node := range nodesToCreate {
|
|
| 454 |
- if err := createDeviceNode(rootfs, node); err != nil {
|
|
| 455 |
- return err |
|
| 456 |
- } |
|
| 457 |
- } |
|
| 458 |
- return nil |
|
| 459 |
-} |
|
| 460 |
- |
|
| 461 |
-// Creates the device node in the rootfs of the container. |
|
| 462 |
-func createDeviceNode(rootfs string, node *configs.Device) error {
|
|
| 463 |
- var ( |
|
| 464 |
- dest = filepath.Join(rootfs, node.Path) |
|
| 465 |
- parent = filepath.Dir(dest) |
|
| 466 |
- ) |
|
| 467 |
- |
|
| 468 |
- if err := os.MkdirAll(parent, 0755); err != nil {
|
|
| 469 |
- return err |
|
| 470 |
- } |
|
| 471 |
- |
|
| 472 |
- fileMode := node.FileMode |
|
| 473 |
- switch node.Type {
|
|
| 474 |
- case 'c': |
|
| 475 |
- fileMode |= syscall.S_IFCHR |
|
| 476 |
- case 'b': |
|
| 477 |
- fileMode |= syscall.S_IFBLK |
|
| 478 |
- default: |
|
| 479 |
- return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
|
|
| 480 |
- } |
|
| 481 |
- |
|
| 482 |
- if err := syscall.Mknod(dest, uint32(fileMode), node.Mkdev()); err != nil && !os.IsExist(err) {
|
|
| 483 |
- return fmt.Errorf("mknod %s %s", node.Path, err)
|
|
| 484 |
- } |
|
| 485 |
- |
|
| 486 |
- if err := syscall.Chown(dest, int(node.Uid), int(node.Gid)); err != nil {
|
|
| 487 |
- return fmt.Errorf("chown %s to %d:%d", node.Path, node.Uid, node.Gid)
|
|
| 488 |
- } |
|
| 489 |
- |
|
| 490 |
- return nil |
|
| 491 |
-} |
|
| 492 |
- |
|
| 493 |
-// setupUser changes the groups, gid, and uid for the user inside the container |
|
| 494 |
-// copy from libcontainer, cause not it's private |
|
| 495 |
-func setupUser(userSpec string) error {
|
|
| 496 |
- // Set up defaults. |
|
| 497 |
- defaultExecUser := user.ExecUser{
|
|
| 498 |
- Uid: syscall.Getuid(), |
|
| 499 |
- Gid: syscall.Getgid(), |
|
| 500 |
- Home: "/", |
|
| 501 |
- } |
|
| 502 |
- passwdPath, err := user.GetPasswdPath() |
|
| 503 |
- if err != nil {
|
|
| 504 |
- return err |
|
| 505 |
- } |
|
| 506 |
- groupPath, err := user.GetGroupPath() |
|
| 507 |
- if err != nil {
|
|
| 508 |
- return err |
|
| 509 |
- } |
|
| 510 |
- execUser, err := user.GetExecUserPath(userSpec, &defaultExecUser, passwdPath, groupPath) |
|
| 511 |
- if err != nil {
|
|
| 512 |
- return err |
|
| 513 |
- } |
|
| 514 |
- if err := syscall.Setgroups(execUser.Sgids); err != nil {
|
|
| 515 |
- return err |
|
| 516 |
- } |
|
| 517 |
- if err := system.Setgid(execUser.Gid); err != nil {
|
|
| 518 |
- return err |
|
| 519 |
- } |
|
| 520 |
- if err := system.Setuid(execUser.Uid); err != nil {
|
|
| 521 |
- return err |
|
| 522 |
- } |
|
| 523 |
- // if we didn't get HOME already, set it based on the user's HOME |
|
| 524 |
- if envHome := os.Getenv("HOME"); envHome == "" {
|
|
| 525 |
- if err := os.Setenv("HOME", execUser.Home); err != nil {
|
|
| 526 |
- return err |
|
| 527 |
- } |
|
| 528 |
- } |
|
| 529 |
- return nil |
|
| 530 |
-} |
|
| 531 |
- |
|
| 532 |
-// getExitCode returns the exit code of the process. |
|
| 533 |
-// If the process has not exited -1 will be returned. |
|
| 534 |
-func getExitCode(c *execdriver.Command) int {
|
|
| 535 |
- if c.ProcessConfig.ProcessState == nil {
|
|
| 536 |
- return -1 |
|
| 537 |
- } |
|
| 538 |
- return c.ProcessConfig.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() |
|
| 539 |
-} |
|
| 540 |
- |
|
| 541 |
-// Kill implements the exec driver Driver interface. |
|
| 542 |
-func (d *Driver) Kill(c *execdriver.Command, sig int) error {
|
|
| 543 |
- if sig == 9 || c.ProcessConfig.Process == nil {
|
|
| 544 |
- return killLxc(c.ID, sig) |
|
| 545 |
- } |
|
| 546 |
- |
|
| 547 |
- return c.ProcessConfig.Process.Signal(syscall.Signal(sig)) |
|
| 548 |
-} |
|
| 549 |
- |
|
| 550 |
-// Pause implements the exec driver Driver interface, |
|
| 551 |
-// it executes lxc-freeze to pause a container. |
|
| 552 |
-func (d *Driver) Pause(c *execdriver.Command) error {
|
|
| 553 |
- _, err := exec.LookPath("lxc-freeze")
|
|
| 554 |
- if err == nil {
|
|
| 555 |
- output, errExec := exec.Command("lxc-freeze", "-n", c.ID).CombinedOutput()
|
|
| 556 |
- if errExec != nil {
|
|
| 557 |
- return fmt.Errorf("Err: %s Output: %s", errExec, output)
|
|
| 558 |
- } |
|
| 559 |
- } |
|
| 560 |
- |
|
| 561 |
- return err |
|
| 562 |
-} |
|
| 563 |
- |
|
| 564 |
-// Unpause implements the exec driver Driver interface, |
|
| 565 |
-// it executes lxc-unfreeze to unpause a container. |
|
| 566 |
-func (d *Driver) Unpause(c *execdriver.Command) error {
|
|
| 567 |
- _, err := exec.LookPath("lxc-unfreeze")
|
|
| 568 |
- if err == nil {
|
|
| 569 |
- output, errExec := exec.Command("lxc-unfreeze", "-n", c.ID).CombinedOutput()
|
|
| 570 |
- if errExec != nil {
|
|
| 571 |
- return fmt.Errorf("Err: %s Output: %s", errExec, output)
|
|
| 572 |
- } |
|
| 573 |
- } |
|
| 574 |
- |
|
| 575 |
- return err |
|
| 576 |
-} |
|
| 577 |
- |
|
| 578 |
-// Terminate implements the exec driver Driver interface. |
|
| 579 |
-func (d *Driver) Terminate(c *execdriver.Command) error {
|
|
| 580 |
- return killLxc(c.ID, 9) |
|
| 581 |
-} |
|
| 582 |
- |
|
| 583 |
-func (d *Driver) version() string {
|
|
| 584 |
- var ( |
|
| 585 |
- version string |
|
| 586 |
- output []byte |
|
| 587 |
- err error |
|
| 588 |
- ) |
|
| 589 |
- if _, errPath := exec.LookPath("lxc-version"); errPath == nil {
|
|
| 590 |
- output, err = exec.Command("lxc-version").CombinedOutput()
|
|
| 591 |
- } else {
|
|
| 592 |
- output, err = exec.Command("lxc-start", "--version").CombinedOutput()
|
|
| 593 |
- } |
|
| 594 |
- if err == nil {
|
|
| 595 |
- version = strings.TrimSpace(string(output)) |
|
| 596 |
- if parts := strings.SplitN(version, ":", 2); len(parts) == 2 {
|
|
| 597 |
- version = strings.TrimSpace(parts[1]) |
|
| 598 |
- } |
|
| 599 |
- } |
|
| 600 |
- return version |
|
| 601 |
-} |
|
| 602 |
- |
|
| 603 |
-func killLxc(id string, sig int) error {
|
|
| 604 |
- var ( |
|
| 605 |
- err error |
|
| 606 |
- output []byte |
|
| 607 |
- ) |
|
| 608 |
- _, err = exec.LookPath("lxc-kill")
|
|
| 609 |
- if err == nil {
|
|
| 610 |
- output, err = exec.Command("lxc-kill", "-n", id, strconv.Itoa(sig)).CombinedOutput()
|
|
| 611 |
- } else {
|
|
| 612 |
- // lxc-stop does not take arbitrary signals like lxc-kill does |
|
| 613 |
- output, err = exec.Command("lxc-stop", "-k", "-n", id).CombinedOutput()
|
|
| 614 |
- } |
|
| 615 |
- if err != nil {
|
|
| 616 |
- return fmt.Errorf("Err: %s Output: %s", err, output)
|
|
| 617 |
- } |
|
| 618 |
- return nil |
|
| 619 |
-} |
|
| 620 |
- |
|
| 621 |
-// wait for the process to start and return the pid for the process |
|
| 622 |
-func (d *Driver) waitForStart(c *execdriver.Command, waitLock chan struct{}) (int, error) {
|
|
| 623 |
- var ( |
|
| 624 |
- err error |
|
| 625 |
- output []byte |
|
| 626 |
- ) |
|
| 627 |
- // We wait for the container to be fully running. |
|
| 628 |
- // Timeout after 5 seconds. In case of broken pipe, just retry. |
|
| 629 |
- // Note: The container can run and finish correctly before |
|
| 630 |
- // the end of this loop |
|
| 631 |
- for now := time.Now(); time.Since(now) < 5*time.Second; {
|
|
| 632 |
- select {
|
|
| 633 |
- case <-waitLock: |
|
| 634 |
- // If the process dies while waiting for it, just return |
|
| 635 |
- return -1, nil |
|
| 636 |
- default: |
|
| 637 |
- } |
|
| 638 |
- |
|
| 639 |
- output, err = d.getInfo(c.ID) |
|
| 640 |
- if err == nil {
|
|
| 641 |
- info, err := parseLxcInfo(string(output)) |
|
| 642 |
- if err != nil {
|
|
| 643 |
- return -1, err |
|
| 644 |
- } |
|
| 645 |
- if info.Running {
|
|
| 646 |
- return info.Pid, nil |
|
| 647 |
- } |
|
| 648 |
- } |
|
| 649 |
- time.Sleep(50 * time.Millisecond) |
|
| 650 |
- } |
|
| 651 |
- return -1, execdriver.ErrNotRunning |
|
| 652 |
-} |
|
| 653 |
- |
|
| 654 |
-func (d *Driver) getInfo(id string) ([]byte, error) {
|
|
| 655 |
- return exec.Command("lxc-info", "-n", id).CombinedOutput()
|
|
| 656 |
-} |
|
| 657 |
- |
|
| 658 |
-type info struct {
|
|
| 659 |
- ID string |
|
| 660 |
- driver *Driver |
|
| 661 |
-} |
|
| 662 |
- |
|
| 663 |
-func (i *info) IsRunning() bool {
|
|
| 664 |
- var running bool |
|
| 665 |
- |
|
| 666 |
- output, err := i.driver.getInfo(i.ID) |
|
| 667 |
- if err != nil {
|
|
| 668 |
- logrus.Errorf("Error getting info for lxc container %s: %s (%s)", i.ID, err, output)
|
|
| 669 |
- return false |
|
| 670 |
- } |
|
| 671 |
- if strings.Contains(string(output), "RUNNING") {
|
|
| 672 |
- running = true |
|
| 673 |
- } |
|
| 674 |
- return running |
|
| 675 |
-} |
|
| 676 |
- |
|
| 677 |
-// Info implements the exec driver Driver interface. |
|
| 678 |
-func (d *Driver) Info(id string) execdriver.Info {
|
|
| 679 |
- return &info{
|
|
| 680 |
- ID: id, |
|
| 681 |
- driver: d, |
|
| 682 |
- } |
|
| 683 |
-} |
|
| 684 |
- |
|
| 685 |
-func findCgroupRootAndDir(subsystem string) (string, string, error) {
|
|
| 686 |
- cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem) |
|
| 687 |
- if err != nil {
|
|
| 688 |
- return "", "", err |
|
| 689 |
- } |
|
| 690 |
- |
|
| 691 |
- cgroupDir, err := cgroups.GetThisCgroupDir(subsystem) |
|
| 692 |
- if err != nil {
|
|
| 693 |
- return "", "", err |
|
| 694 |
- } |
|
| 695 |
- return cgroupRoot, cgroupDir, nil |
|
| 696 |
-} |
|
| 697 |
- |
|
| 698 |
-// GetPidsForContainer implements the exec driver Driver interface. |
|
| 699 |
-func (d *Driver) GetPidsForContainer(id string) ([]int, error) {
|
|
| 700 |
- pids := []int{}
|
|
| 701 |
- |
|
| 702 |
- // cpu is chosen because it is the only non optional subsystem in cgroups |
|
| 703 |
- subsystem := "cpu" |
|
| 704 |
- cgroupRoot, cgroupDir, err := findCgroupRootAndDir(subsystem) |
|
| 705 |
- if err != nil {
|
|
| 706 |
- return pids, err |
|
| 707 |
- } |
|
| 708 |
- |
|
| 709 |
- filename := filepath.Join(cgroupRoot, cgroupDir, id, "tasks") |
|
| 710 |
- if _, err := os.Stat(filename); os.IsNotExist(err) {
|
|
| 711 |
- // With more recent lxc versions use, cgroup will be in lxc/ |
|
| 712 |
- filename = filepath.Join(cgroupRoot, cgroupDir, "lxc", id, "tasks") |
|
| 713 |
- } |
|
| 714 |
- |
|
| 715 |
- output, err := ioutil.ReadFile(filename) |
|
| 716 |
- if err != nil {
|
|
| 717 |
- return pids, err |
|
| 718 |
- } |
|
| 719 |
- for _, p := range strings.Split(string(output), "\n") {
|
|
| 720 |
- if len(p) == 0 {
|
|
| 721 |
- continue |
|
| 722 |
- } |
|
| 723 |
- pid, err := strconv.Atoi(p) |
|
| 724 |
- if err != nil {
|
|
| 725 |
- return pids, fmt.Errorf("Invalid pid '%s': %s", p, err)
|
|
| 726 |
- } |
|
| 727 |
- pids = append(pids, pid) |
|
| 728 |
- } |
|
| 729 |
- return pids, nil |
|
| 730 |
-} |
|
| 731 |
- |
|
| 732 |
-func linkLxcStart(root string) error {
|
|
| 733 |
- sourcePath, err := exec.LookPath("lxc-start")
|
|
| 734 |
- if err != nil {
|
|
| 735 |
- return err |
|
| 736 |
- } |
|
| 737 |
- targetPath := path.Join(root, "lxc-start-unconfined") |
|
| 738 |
- |
|
| 739 |
- if _, err := os.Lstat(targetPath); err != nil && !os.IsNotExist(err) {
|
|
| 740 |
- return err |
|
| 741 |
- } else if err == nil {
|
|
| 742 |
- if err := os.Remove(targetPath); err != nil {
|
|
| 743 |
- return err |
|
| 744 |
- } |
|
| 745 |
- } |
|
| 746 |
- return os.Symlink(sourcePath, targetPath) |
|
| 747 |
-} |
|
| 748 |
- |
|
| 749 |
-// TODO: This can be moved to the mountinfo reader in the mount pkg |
|
| 750 |
-func rootIsShared() bool {
|
|
| 751 |
- if data, err := ioutil.ReadFile("/proc/self/mountinfo"); err == nil {
|
|
| 752 |
- for _, line := range strings.Split(string(data), "\n") {
|
|
| 753 |
- cols := strings.Split(line, " ") |
|
| 754 |
- if len(cols) >= 6 && cols[4] == "/" {
|
|
| 755 |
- return strings.HasPrefix(cols[6], "shared") |
|
| 756 |
- } |
|
| 757 |
- } |
|
| 758 |
- } |
|
| 759 |
- |
|
| 760 |
- // No idea, probably safe to assume so |
|
| 761 |
- return true |
|
| 762 |
-} |
|
| 763 |
- |
|
| 764 |
-func (d *Driver) containerDir(containerID string) string {
|
|
| 765 |
- return path.Join(d.libPath, "containers", containerID) |
|
| 766 |
-} |
|
| 767 |
- |
|
| 768 |
-func (d *Driver) generateLXCConfig(c *execdriver.Command) (string, error) {
|
|
| 769 |
- root := path.Join(d.containerDir(c.ID), "config.lxc") |
|
| 770 |
- |
|
| 771 |
- fo, err := os.Create(root) |
|
| 772 |
- if err != nil {
|
|
| 773 |
- return "", err |
|
| 774 |
- } |
|
| 775 |
- defer fo.Close() |
|
| 776 |
- |
|
| 777 |
- if err := lxcTemplateCompiled.Execute(fo, struct {
|
|
| 778 |
- *execdriver.Command |
|
| 779 |
- AppArmor bool |
|
| 780 |
- }{
|
|
| 781 |
- Command: c, |
|
| 782 |
- AppArmor: d.apparmor, |
|
| 783 |
- }); err != nil {
|
|
| 784 |
- return "", err |
|
| 785 |
- } |
|
| 786 |
- |
|
| 787 |
- return root, nil |
|
| 788 |
-} |
|
| 789 |
- |
|
| 790 |
-func (d *Driver) generateEnvConfig(c *execdriver.Command) error {
|
|
| 791 |
- data, err := json.Marshal(c.ProcessConfig.Env) |
|
| 792 |
- if err != nil {
|
|
| 793 |
- return err |
|
| 794 |
- } |
|
| 795 |
- p := path.Join(d.libPath, "containers", c.ID, "config.env") |
|
| 796 |
- c.Mounts = append(c.Mounts, execdriver.Mount{
|
|
| 797 |
- Source: p, |
|
| 798 |
- Destination: "/.dockerenv", |
|
| 799 |
- Writable: false, |
|
| 800 |
- Private: true, |
|
| 801 |
- }) |
|
| 802 |
- |
|
| 803 |
- return ioutil.WriteFile(p, data, 0600) |
|
| 804 |
-} |
|
| 805 |
- |
|
| 806 |
-// Clean implements the exec driver Driver interface, |
|
| 807 |
-// it's not implemented by lxc. |
|
| 808 |
-func (d *Driver) Clean(id string) error {
|
|
| 809 |
- return nil |
|
| 810 |
-} |
|
| 811 |
- |
|
| 812 |
-// TtyConsole implements the exec driver Terminal interface, |
|
| 813 |
-// it stores the master and slave ends of the container's pty. |
|
| 814 |
-type TtyConsole struct {
|
|
| 815 |
- MasterPty *os.File |
|
| 816 |
- SlavePty *os.File |
|
| 817 |
-} |
|
| 818 |
- |
|
| 819 |
-// NewTtyConsole returns a new TtyConsole struct. |
|
| 820 |
-// Wired up to the provided process config and stdin/stdout/stderr pipes. |
|
| 821 |
-func NewTtyConsole(processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes) (*TtyConsole, error) {
|
|
| 822 |
- // lxc is special in that we cannot create the master outside of the container without |
|
| 823 |
- // opening the slave because we have nothing to provide to the cmd. We have to open both then do |
|
| 824 |
- // the crazy setup on command right now instead of passing the console path to lxc and telling it |
|
| 825 |
- // to open up that console. we save a couple of openfiles in the native driver because we can do |
|
| 826 |
- // this. |
|
| 827 |
- ptyMaster, ptySlave, err := pty.Open() |
|
| 828 |
- if err != nil {
|
|
| 829 |
- return nil, err |
|
| 830 |
- } |
|
| 831 |
- |
|
| 832 |
- tty := &TtyConsole{
|
|
| 833 |
- MasterPty: ptyMaster, |
|
| 834 |
- SlavePty: ptySlave, |
|
| 835 |
- } |
|
| 836 |
- |
|
| 837 |
- if err := tty.AttachPipes(&processConfig.Cmd, pipes); err != nil {
|
|
| 838 |
- tty.Close() |
|
| 839 |
- return nil, err |
|
| 840 |
- } |
|
| 841 |
- |
|
| 842 |
- processConfig.Console = tty.SlavePty.Name() |
|
| 843 |
- |
|
| 844 |
- return tty, nil |
|
| 845 |
-} |
|
| 846 |
- |
|
| 847 |
-// Resize implements Resize method of Terminal interface |
|
| 848 |
-func (t *TtyConsole) Resize(h, w int) error {
|
|
| 849 |
- return term.SetWinsize(t.MasterPty.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
|
|
| 850 |
-} |
|
| 851 |
- |
|
| 852 |
-// AttachPipes attaches given pipes to exec.Cmd |
|
| 853 |
-func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *execdriver.Pipes) error {
|
|
| 854 |
- command.Stdout = t.SlavePty |
|
| 855 |
- command.Stderr = t.SlavePty |
|
| 856 |
- |
|
| 857 |
- go func() {
|
|
| 858 |
- if wb, ok := pipes.Stdout.(interface {
|
|
| 859 |
- CloseWriters() error |
|
| 860 |
- }); ok {
|
|
| 861 |
- defer wb.CloseWriters() |
|
| 862 |
- } |
|
| 863 |
- |
|
| 864 |
- io.Copy(pipes.Stdout, t.MasterPty) |
|
| 865 |
- }() |
|
| 866 |
- |
|
| 867 |
- if pipes.Stdin != nil {
|
|
| 868 |
- command.Stdin = t.SlavePty |
|
| 869 |
- command.SysProcAttr.Setctty = true |
|
| 870 |
- |
|
| 871 |
- go func() {
|
|
| 872 |
- io.Copy(t.MasterPty, pipes.Stdin) |
|
| 873 |
- |
|
| 874 |
- pipes.Stdin.Close() |
|
| 875 |
- }() |
|
| 876 |
- } |
|
| 877 |
- return nil |
|
| 878 |
-} |
|
| 879 |
- |
|
| 880 |
-// Close implements Close method of Terminal interface |
|
| 881 |
-func (t *TtyConsole) Close() error {
|
|
| 882 |
- t.SlavePty.Close() |
|
| 883 |
- return t.MasterPty.Close() |
|
| 884 |
-} |
|
| 885 |
- |
|
| 886 |
-// Exec implements the exec driver Driver interface, |
|
| 887 |
-// it is not implemented by lxc. |
|
| 888 |
-func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, hooks execdriver.Hooks) (int, error) {
|
|
| 889 |
- return -1, ErrExec |
|
| 890 |
-} |
|
| 891 |
- |
|
| 892 |
-// Stats implements the exec driver Driver interface. |
|
| 893 |
-// Lxc doesn't implement it's own Stats, it does some trick by implementing |
|
| 894 |
-// execdriver.Stats to get stats info by libcontainer APIs. |
|
| 895 |
-func (d *Driver) Stats(id string) (*execdriver.ResourceStats, error) {
|
|
| 896 |
- if _, ok := d.activeContainers[id]; !ok {
|
|
| 897 |
- return nil, fmt.Errorf("%s is not a key in active containers", id)
|
|
| 898 |
- } |
|
| 899 |
- return execdriver.Stats(d.containerDir(id), d.activeContainers[id].container.Cgroups.Memory, d.machineMemory) |
|
| 900 |
-} |
|
| 901 |
- |
|
| 902 |
-// SupportsHooks implements the execdriver Driver interface. |
|
| 903 |
-// The LXC execdriver does not support the hook mechanism, which is currently unique to runC/libcontainer. |
|
| 904 |
-func (d *Driver) SupportsHooks() bool {
|
|
| 905 |
- return false |
|
| 906 |
-} |
| 907 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,53 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "bufio" |
|
| 7 |
- "errors" |
|
| 8 |
- "strconv" |
|
| 9 |
- "strings" |
|
| 10 |
-) |
|
| 11 |
- |
|
| 12 |
-// Define error messages |
|
| 13 |
-var ( |
|
| 14 |
- ErrCannotParse = errors.New("cannot parse raw input")
|
|
| 15 |
-) |
|
| 16 |
- |
|
| 17 |
-type lxcInfo struct {
|
|
| 18 |
- Running bool |
|
| 19 |
- Pid int |
|
| 20 |
-} |
|
| 21 |
- |
|
| 22 |
-func parseLxcInfo(raw string) (*lxcInfo, error) {
|
|
| 23 |
- if raw == "" {
|
|
| 24 |
- return nil, ErrCannotParse |
|
| 25 |
- } |
|
| 26 |
- var ( |
|
| 27 |
- err error |
|
| 28 |
- s = bufio.NewScanner(strings.NewReader(raw)) |
|
| 29 |
- info = &lxcInfo{}
|
|
| 30 |
- ) |
|
| 31 |
- for s.Scan() {
|
|
| 32 |
- text := s.Text() |
|
| 33 |
- |
|
| 34 |
- if s.Err() != nil {
|
|
| 35 |
- return nil, s.Err() |
|
| 36 |
- } |
|
| 37 |
- |
|
| 38 |
- parts := strings.Split(text, ":") |
|
| 39 |
- if len(parts) < 2 {
|
|
| 40 |
- continue |
|
| 41 |
- } |
|
| 42 |
- switch strings.ToLower(strings.TrimSpace(parts[0])) {
|
|
| 43 |
- case "state": |
|
| 44 |
- info.Running = strings.TrimSpace(parts[1]) == "RUNNING" |
|
| 45 |
- case "pid": |
|
| 46 |
- info.Pid, err = strconv.Atoi(strings.TrimSpace(parts[1])) |
|
| 47 |
- if err != nil {
|
|
| 48 |
- return nil, err |
|
| 49 |
- } |
|
| 50 |
- } |
|
| 51 |
- } |
|
| 52 |
- return info, nil |
|
| 53 |
-} |
| 54 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,38 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "testing" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-func TestParseRunningInfo(t *testing.T) {
|
|
| 10 |
- raw := ` |
|
| 11 |
- state: RUNNING |
|
| 12 |
- pid: 50` |
|
| 13 |
- |
|
| 14 |
- info, err := parseLxcInfo(raw) |
|
| 15 |
- if err != nil {
|
|
| 16 |
- t.Fatal(err) |
|
| 17 |
- } |
|
| 18 |
- if !info.Running {
|
|
| 19 |
- t.Fatal("info should return a running state")
|
|
| 20 |
- } |
|
| 21 |
- if info.Pid != 50 {
|
|
| 22 |
- t.Fatalf("info should have pid 50 got %d", info.Pid)
|
|
| 23 |
- } |
|
| 24 |
-} |
|
| 25 |
- |
|
| 26 |
-func TestEmptyInfo(t *testing.T) {
|
|
| 27 |
- _, err := parseLxcInfo("")
|
|
| 28 |
- if err == nil {
|
|
| 29 |
- t.Fatal("error should not be nil")
|
|
| 30 |
- } |
|
| 31 |
-} |
|
| 32 |
- |
|
| 33 |
-func TestBadInfo(t *testing.T) {
|
|
| 34 |
- _, err := parseLxcInfo("state")
|
|
| 35 |
- if err != nil {
|
|
| 36 |
- t.Fatal(err) |
|
| 37 |
- } |
|
| 38 |
-} |
| 39 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,145 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "encoding/json" |
|
| 7 |
- "flag" |
|
| 8 |
- "fmt" |
|
| 9 |
- "os" |
|
| 10 |
- "os/exec" |
|
| 11 |
- "runtime" |
|
| 12 |
- "strings" |
|
| 13 |
- "syscall" |
|
| 14 |
- |
|
| 15 |
- "github.com/Sirupsen/logrus" |
|
| 16 |
- "github.com/docker/docker/pkg/reexec" |
|
| 17 |
-) |
|
| 18 |
- |
|
| 19 |
-// InitArgs contains args provided to the init function for a driver |
|
| 20 |
-type InitArgs struct {
|
|
| 21 |
- User string |
|
| 22 |
- Gateway string |
|
| 23 |
- IP string |
|
| 24 |
- WorkDir string |
|
| 25 |
- Privileged bool |
|
| 26 |
- Env []string |
|
| 27 |
- Args []string |
|
| 28 |
- Mtu int |
|
| 29 |
- Console string |
|
| 30 |
- Pipe int |
|
| 31 |
- Root string |
|
| 32 |
- CapAdd string |
|
| 33 |
- CapDrop string |
|
| 34 |
-} |
|
| 35 |
- |
|
| 36 |
-func init() {
|
|
| 37 |
- // like always lxc requires a hack to get this to work |
|
| 38 |
- reexec.Register("/.dockerinit", dockerInititalizer)
|
|
| 39 |
-} |
|
| 40 |
- |
|
| 41 |
-func dockerInititalizer() {
|
|
| 42 |
- initializer() |
|
| 43 |
-} |
|
| 44 |
- |
|
| 45 |
-// initializer is the lxc driver's init function that is run inside the namespace to setup |
|
| 46 |
-// additional configurations |
|
| 47 |
-func initializer() {
|
|
| 48 |
- runtime.LockOSThread() |
|
| 49 |
- |
|
| 50 |
- args := getArgs() |
|
| 51 |
- |
|
| 52 |
- if err := setupNamespace(args); err != nil {
|
|
| 53 |
- logrus.Fatal(err) |
|
| 54 |
- } |
|
| 55 |
-} |
|
| 56 |
- |
|
| 57 |
-func setupNamespace(args *InitArgs) error {
|
|
| 58 |
- if err := setupEnv(args); err != nil {
|
|
| 59 |
- return err |
|
| 60 |
- } |
|
| 61 |
- |
|
| 62 |
- if err := finalizeNamespace(args); err != nil {
|
|
| 63 |
- return err |
|
| 64 |
- } |
|
| 65 |
- |
|
| 66 |
- path, err := exec.LookPath(args.Args[0]) |
|
| 67 |
- if err != nil {
|
|
| 68 |
- logrus.Infof("Unable to locate %v", args.Args[0])
|
|
| 69 |
- os.Exit(127) |
|
| 70 |
- } |
|
| 71 |
- |
|
| 72 |
- if err := syscall.Exec(path, args.Args, os.Environ()); err != nil {
|
|
| 73 |
- return fmt.Errorf("dockerinit unable to execute %s - %s", path, err)
|
|
| 74 |
- } |
|
| 75 |
- |
|
| 76 |
- return nil |
|
| 77 |
-} |
|
| 78 |
- |
|
| 79 |
-func getArgs() *InitArgs {
|
|
| 80 |
- var ( |
|
| 81 |
- // Get cmdline arguments |
|
| 82 |
- user = flag.String("u", "", "username or uid")
|
|
| 83 |
- gateway = flag.String("g", "", "gateway address")
|
|
| 84 |
- ip = flag.String("i", "", "ip address")
|
|
| 85 |
- workDir = flag.String("w", "", "workdir")
|
|
| 86 |
- privileged = flag.Bool("privileged", false, "privileged mode")
|
|
| 87 |
- mtu = flag.Int("mtu", 1500, "interface mtu")
|
|
| 88 |
- capAdd = flag.String("cap-add", "", "capabilities to add")
|
|
| 89 |
- capDrop = flag.String("cap-drop", "", "capabilities to drop")
|
|
| 90 |
- ) |
|
| 91 |
- |
|
| 92 |
- flag.Parse() |
|
| 93 |
- |
|
| 94 |
- return &InitArgs{
|
|
| 95 |
- User: *user, |
|
| 96 |
- Gateway: *gateway, |
|
| 97 |
- IP: *ip, |
|
| 98 |
- WorkDir: *workDir, |
|
| 99 |
- Privileged: *privileged, |
|
| 100 |
- Args: flag.Args(), |
|
| 101 |
- Mtu: *mtu, |
|
| 102 |
- CapAdd: *capAdd, |
|
| 103 |
- CapDrop: *capDrop, |
|
| 104 |
- } |
|
| 105 |
-} |
|
| 106 |
- |
|
| 107 |
-// Clear environment pollution introduced by lxc-start |
|
| 108 |
-func setupEnv(args *InitArgs) error {
|
|
| 109 |
- // Get env |
|
| 110 |
- var env []string |
|
| 111 |
- dockerenv, err := os.Open(".dockerenv")
|
|
| 112 |
- if err != nil {
|
|
| 113 |
- return fmt.Errorf("Unable to load environment variables: %v", err)
|
|
| 114 |
- } |
|
| 115 |
- defer dockerenv.Close() |
|
| 116 |
- if err := json.NewDecoder(dockerenv).Decode(&env); err != nil {
|
|
| 117 |
- return fmt.Errorf("Unable to decode environment variables: %v", err)
|
|
| 118 |
- } |
|
| 119 |
- // Propagate the plugin-specific container env variable |
|
| 120 |
- env = append(env, "container="+os.Getenv("container"))
|
|
| 121 |
- |
|
| 122 |
- args.Env = env |
|
| 123 |
- |
|
| 124 |
- os.Clearenv() |
|
| 125 |
- for _, kv := range args.Env {
|
|
| 126 |
- parts := strings.SplitN(kv, "=", 2) |
|
| 127 |
- if len(parts) == 1 {
|
|
| 128 |
- parts = append(parts, "") |
|
| 129 |
- } |
|
| 130 |
- os.Setenv(parts[0], parts[1]) |
|
| 131 |
- } |
|
| 132 |
- |
|
| 133 |
- return nil |
|
| 134 |
-} |
|
| 135 |
- |
|
| 136 |
-// Setup working directory |
|
| 137 |
-func setupWorkingDirectory(args *InitArgs) error {
|
|
| 138 |
- if args.WorkDir == "" {
|
|
| 139 |
- return nil |
|
| 140 |
- } |
|
| 141 |
- if err := syscall.Chdir(args.WorkDir); err != nil {
|
|
| 142 |
- return fmt.Errorf("Unable to change dir to %v: %v", args.WorkDir, err)
|
|
| 143 |
- } |
|
| 144 |
- return nil |
|
| 145 |
-} |
| 146 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,22 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "fmt" |
|
| 7 |
- |
|
| 8 |
- "github.com/opencontainers/runc/libcontainer/utils" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-func finalizeNamespace(args *InitArgs) error {
|
|
| 12 |
- if err := utils.CloseExecFrom(3); err != nil {
|
|
| 13 |
- return err |
|
| 14 |
- } |
|
| 15 |
- if err := setupUser(args.User); err != nil {
|
|
| 16 |
- return fmt.Errorf("setup user %s", err)
|
|
| 17 |
- } |
|
| 18 |
- if err := setupWorkingDirectory(args); err != nil {
|
|
| 19 |
- return err |
|
| 20 |
- } |
|
| 21 |
- return nil |
|
| 22 |
-} |
| 23 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,11 +0,0 @@ |
| 1 |
-// +build !linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-// InitArgs contains args provided to the init function for a driver |
|
| 6 |
-type InitArgs struct {
|
|
| 7 |
-} |
|
| 8 |
- |
|
| 9 |
-func finalizeNamespace(args *InitArgs) error {
|
|
| 10 |
- panic("Not supported on this platform")
|
|
| 11 |
-} |
| 12 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,247 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "fmt" |
|
| 7 |
- "os" |
|
| 8 |
- "strings" |
|
| 9 |
- "text/template" |
|
| 10 |
- |
|
| 11 |
- "github.com/Sirupsen/logrus" |
|
| 12 |
- "github.com/docker/docker/daemon/execdriver" |
|
| 13 |
- nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template" |
|
| 14 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 15 |
- "github.com/opencontainers/runc/libcontainer/label" |
|
| 16 |
-) |
|
| 17 |
- |
|
| 18 |
-// LxcTemplate is the template for lxc driver, it's used |
|
| 19 |
-// to configure LXC. |
|
| 20 |
-const LxcTemplate = ` |
|
| 21 |
-lxc.network.type = none |
|
| 22 |
-# root filesystem |
|
| 23 |
-{{$ROOTFS := .Rootfs}}
|
|
| 24 |
-lxc.rootfs = {{$ROOTFS}}
|
|
| 25 |
- |
|
| 26 |
-# use a dedicated pts for the container (and limit the number of pseudo terminal |
|
| 27 |
-# available) |
|
| 28 |
-lxc.pts = 1024 |
|
| 29 |
- |
|
| 30 |
-# disable the main console |
|
| 31 |
-lxc.console = none |
|
| 32 |
- |
|
| 33 |
-# no controlling tty at all |
|
| 34 |
-lxc.tty = 1 |
|
| 35 |
- |
|
| 36 |
-{{if .ProcessConfig.Privileged}}
|
|
| 37 |
-lxc.cgroup.devices.allow = a |
|
| 38 |
-{{else}}
|
|
| 39 |
-# no implicit access to devices |
|
| 40 |
-lxc.cgroup.devices.deny = a |
|
| 41 |
-#Allow the devices passed to us in the AllowedDevices list. |
|
| 42 |
-{{range $allowedDevice := .AllowedDevices}}
|
|
| 43 |
-lxc.cgroup.devices.allow = {{$allowedDevice.CgroupString}}
|
|
| 44 |
-{{end}}
|
|
| 45 |
-{{end}}
|
|
| 46 |
- |
|
| 47 |
-# standard mount point |
|
| 48 |
-# Use mnt.putold as per https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/986385 |
|
| 49 |
-lxc.pivotdir = lxc_putold |
|
| 50 |
- |
|
| 51 |
-# lxc.autodev is not compatible with lxc --device switch |
|
| 52 |
-lxc.autodev = 0 |
|
| 53 |
- |
|
| 54 |
-# NOTICE: These mounts must be applied within the namespace |
|
| 55 |
-{{if .ProcessConfig.Privileged}}
|
|
| 56 |
-# WARNING: mounting procfs and/or sysfs read-write is a known attack vector. |
|
| 57 |
-# See e.g. http://blog.zx2c4.com/749 and https://bit.ly/T9CkqJ |
|
| 58 |
-# We mount them read-write here, but later, dockerinit will call the Restrict() function to remount them read-only. |
|
| 59 |
-# We cannot mount them directly read-only, because that would prevent loading AppArmor profiles. |
|
| 60 |
-lxc.mount.entry = proc {{escapeFstabSpaces $ROOTFS}}/proc proc nosuid,nodev,noexec 0 0
|
|
| 61 |
-lxc.mount.entry = sysfs {{escapeFstabSpaces $ROOTFS}}/sys sysfs nosuid,nodev,noexec 0 0
|
|
| 62 |
- {{if .AppArmor}}
|
|
| 63 |
-lxc.aa_profile = unconfined |
|
| 64 |
- {{end}}
|
|
| 65 |
-{{else}}
|
|
| 66 |
-# In non-privileged mode, lxc will automatically mount /proc and /sys in readonly mode |
|
| 67 |
-# for security. See: http://man7.org/linux/man-pages/man5/lxc.container.conf.5.html |
|
| 68 |
-lxc.mount.auto = proc sys |
|
| 69 |
- {{if .AppArmorProfile}}
|
|
| 70 |
-lxc.aa_profile = {{.AppArmorProfile}}
|
|
| 71 |
- {{end}}
|
|
| 72 |
-{{end}}
|
|
| 73 |
- |
|
| 74 |
-{{if .ProcessConfig.Tty}}
|
|
| 75 |
-lxc.mount.entry = {{.ProcessConfig.Console}} {{escapeFstabSpaces $ROOTFS}}/dev/console none bind,rw,create=file 0 0
|
|
| 76 |
-{{end}}
|
|
| 77 |
- |
|
| 78 |
-lxc.mount.entry = devpts {{escapeFstabSpaces $ROOTFS}}/dev/pts devpts {{formatMountLabel "newinstance,ptmxmode=0666,nosuid,noexec,create=dir" ""}} 0 0
|
|
| 79 |
-lxc.mount.entry = shm {{escapeFstabSpaces $ROOTFS}}/dev/shm tmpfs {{formatMountLabel "size=65536k,nosuid,nodev,noexec,create=dir" ""}} 0 0
|
|
| 80 |
- |
|
| 81 |
-{{range $value := .Mounts}}
|
|
| 82 |
-{{$createVal := isDirectory $value.Source}}
|
|
| 83 |
-{{if $value.Writable}}
|
|
| 84 |
-lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none rbind,rw,create={{$createVal}} 0 0
|
|
| 85 |
-{{else}}
|
|
| 86 |
-lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabSpaces $value.Destination}} none rbind,ro,create={{$createVal}} 0 0
|
|
| 87 |
-{{end}}
|
|
| 88 |
-{{end}}
|
|
| 89 |
- |
|
| 90 |
-# limits |
|
| 91 |
-{{if .Resources}}
|
|
| 92 |
-{{if .Resources.Memory}}
|
|
| 93 |
-lxc.cgroup.memory.limit_in_bytes = {{.Resources.Memory}}
|
|
| 94 |
-{{end}}
|
|
| 95 |
-{{if gt .Resources.MemorySwap 0}}
|
|
| 96 |
-lxc.cgroup.memory.memsw.limit_in_bytes = {{.Resources.MemorySwap}}
|
|
| 97 |
-{{end}}
|
|
| 98 |
-{{if gt .Resources.MemoryReservation 0}}
|
|
| 99 |
-lxc.cgroup.memory.soft_limit_in_bytes = {{.Resources.MemoryReservation}}
|
|
| 100 |
-{{end}}
|
|
| 101 |
-{{if gt .Resources.KernelMemory 0}}
|
|
| 102 |
-lxc.cgroup.memory.kmem.limit_in_bytes = {{.Resources.KernelMemory}}
|
|
| 103 |
-{{end}}
|
|
| 104 |
-{{if .Resources.CPUShares}}
|
|
| 105 |
-lxc.cgroup.cpu.shares = {{.Resources.CPUShares}}
|
|
| 106 |
-{{end}}
|
|
| 107 |
-{{if .Resources.CPUPeriod}}
|
|
| 108 |
-lxc.cgroup.cpu.cfs_period_us = {{.Resources.CPUPeriod}}
|
|
| 109 |
-{{end}}
|
|
| 110 |
-{{if .Resources.CpusetCpus}}
|
|
| 111 |
-lxc.cgroup.cpuset.cpus = {{.Resources.CpusetCpus}}
|
|
| 112 |
-{{end}}
|
|
| 113 |
-{{if .Resources.CpusetMems}}
|
|
| 114 |
-lxc.cgroup.cpuset.mems = {{.Resources.CpusetMems}}
|
|
| 115 |
-{{end}}
|
|
| 116 |
-{{if .Resources.CPUQuota}}
|
|
| 117 |
-lxc.cgroup.cpu.cfs_quota_us = {{.Resources.CPUQuota}}
|
|
| 118 |
-{{end}}
|
|
| 119 |
-{{if .Resources.BlkioWeight}}
|
|
| 120 |
-lxc.cgroup.blkio.weight = {{.Resources.BlkioWeight}}
|
|
| 121 |
-{{end}}
|
|
| 122 |
-{{if .Resources.OomKillDisable}}
|
|
| 123 |
-lxc.cgroup.memory.oom_control = {{.Resources.OomKillDisable}}
|
|
| 124 |
-{{end}}
|
|
| 125 |
-{{if gt .Resources.MemorySwappiness 0}}
|
|
| 126 |
-lxc.cgroup.memory.swappiness = {{.Resources.MemorySwappiness}}
|
|
| 127 |
-{{end}}
|
|
| 128 |
-{{end}}
|
|
| 129 |
- |
|
| 130 |
-{{if .LxcConfig}}
|
|
| 131 |
-{{range $value := .LxcConfig}}
|
|
| 132 |
-lxc.{{$value}}
|
|
| 133 |
-{{end}}
|
|
| 134 |
-{{end}}
|
|
| 135 |
- |
|
| 136 |
-{{if .ProcessConfig.Env}}
|
|
| 137 |
-lxc.utsname = {{getHostname .ProcessConfig.Env}}
|
|
| 138 |
-{{end}}
|
|
| 139 |
- |
|
| 140 |
-{{if .ProcessConfig.Privileged}}
|
|
| 141 |
-# No cap values are needed, as lxc is starting in privileged mode |
|
| 142 |
-{{else}}
|
|
| 143 |
- {{ with keepCapabilities .CapAdd .CapDrop }}
|
|
| 144 |
- {{range .}}
|
|
| 145 |
-lxc.cap.keep = {{.}}
|
|
| 146 |
- {{end}}
|
|
| 147 |
- {{else}}
|
|
| 148 |
- {{ with dropList .CapDrop }}
|
|
| 149 |
- {{range .}}
|
|
| 150 |
-lxc.cap.drop = {{.}}
|
|
| 151 |
- {{end}}
|
|
| 152 |
- {{end}}
|
|
| 153 |
- {{end}}
|
|
| 154 |
-{{end}}
|
|
| 155 |
-` |
|
| 156 |
- |
|
| 157 |
-var lxcTemplateCompiled *template.Template |
|
| 158 |
- |
|
| 159 |
-// Escape spaces in strings according to the fstab documentation, which is the |
|
| 160 |
-// format for "lxc.mount.entry" lines in lxc.conf. See also "man 5 fstab". |
|
| 161 |
-func escapeFstabSpaces(field string) string {
|
|
| 162 |
- return strings.Replace(field, " ", "\\040", -1) |
|
| 163 |
-} |
|
| 164 |
- |
|
| 165 |
-func keepCapabilities(adds []string, drops []string) ([]string, error) {
|
|
| 166 |
- container := nativeTemplate.New() |
|
| 167 |
- logrus.Debugf("adds %s drops %s\n", adds, drops)
|
|
| 168 |
- caps, err := execdriver.TweakCapabilities(container.Capabilities, adds, drops) |
|
| 169 |
- if err != nil {
|
|
| 170 |
- return nil, err |
|
| 171 |
- } |
|
| 172 |
- var newCaps []string |
|
| 173 |
- for _, cap := range caps {
|
|
| 174 |
- logrus.Debugf("cap %s\n", cap)
|
|
| 175 |
- realCap := execdriver.GetCapability(cap) |
|
| 176 |
- numCap := fmt.Sprintf("%d", realCap.Value)
|
|
| 177 |
- newCaps = append(newCaps, numCap) |
|
| 178 |
- } |
|
| 179 |
- |
|
| 180 |
- return newCaps, nil |
|
| 181 |
-} |
|
| 182 |
- |
|
| 183 |
-func dropList(drops []string) ([]string, error) {
|
|
| 184 |
- if stringutils.InSlice(drops, "all") {
|
|
| 185 |
- var newCaps []string |
|
| 186 |
- for _, capName := range execdriver.GetAllCapabilities() {
|
|
| 187 |
- cap := execdriver.GetCapability(capName) |
|
| 188 |
- logrus.Debugf("drop cap %s\n", cap.Key)
|
|
| 189 |
- numCap := fmt.Sprintf("%d", cap.Value)
|
|
| 190 |
- newCaps = append(newCaps, numCap) |
|
| 191 |
- } |
|
| 192 |
- return newCaps, nil |
|
| 193 |
- } |
|
| 194 |
- return []string{}, nil
|
|
| 195 |
-} |
|
| 196 |
- |
|
| 197 |
-func isDirectory(source string) string {
|
|
| 198 |
- f, err := os.Stat(source) |
|
| 199 |
- logrus.Debugf("dir: %s\n", source)
|
|
| 200 |
- if err != nil {
|
|
| 201 |
- if os.IsNotExist(err) {
|
|
| 202 |
- return "dir" |
|
| 203 |
- } |
|
| 204 |
- return "" |
|
| 205 |
- } |
|
| 206 |
- if f.IsDir() {
|
|
| 207 |
- return "dir" |
|
| 208 |
- } |
|
| 209 |
- return "file" |
|
| 210 |
-} |
|
| 211 |
- |
|
| 212 |
-func getLabel(c map[string][]string, name string) string {
|
|
| 213 |
- label := c["label"] |
|
| 214 |
- for _, l := range label {
|
|
| 215 |
- parts := strings.SplitN(l, "=", 2) |
|
| 216 |
- if strings.TrimSpace(parts[0]) == name {
|
|
| 217 |
- return strings.TrimSpace(parts[1]) |
|
| 218 |
- } |
|
| 219 |
- } |
|
| 220 |
- return "" |
|
| 221 |
-} |
|
| 222 |
- |
|
| 223 |
-func getHostname(env []string) string {
|
|
| 224 |
- for _, kv := range env {
|
|
| 225 |
- parts := strings.SplitN(kv, "=", 2) |
|
| 226 |
- if parts[0] == "HOSTNAME" && len(parts) == 2 {
|
|
| 227 |
- return parts[1] |
|
| 228 |
- } |
|
| 229 |
- } |
|
| 230 |
- return "" |
|
| 231 |
-} |
|
| 232 |
- |
|
| 233 |
-func init() {
|
|
| 234 |
- var err error |
|
| 235 |
- funcMap := template.FuncMap{
|
|
| 236 |
- "escapeFstabSpaces": escapeFstabSpaces, |
|
| 237 |
- "formatMountLabel": label.FormatMountLabel, |
|
| 238 |
- "isDirectory": isDirectory, |
|
| 239 |
- "keepCapabilities": keepCapabilities, |
|
| 240 |
- "dropList": dropList, |
|
| 241 |
- "getHostname": getHostname, |
|
| 242 |
- } |
|
| 243 |
- lxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)
|
|
| 244 |
- if err != nil {
|
|
| 245 |
- panic(err) |
|
| 246 |
- } |
|
| 247 |
-} |
| 248 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,355 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package lxc |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "bufio" |
|
| 7 |
- "fmt" |
|
| 8 |
- "io/ioutil" |
|
| 9 |
- "math/rand" |
|
| 10 |
- "os" |
|
| 11 |
- "path" |
|
| 12 |
- "strings" |
|
| 13 |
- "testing" |
|
| 14 |
- "time" |
|
| 15 |
- |
|
| 16 |
- "github.com/docker/docker/daemon/execdriver" |
|
| 17 |
- nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template" |
|
| 18 |
- "github.com/opencontainers/runc/libcontainer/configs" |
|
| 19 |
- "github.com/syndtr/gocapability/capability" |
|
| 20 |
-) |
|
| 21 |
- |
|
| 22 |
-func TestLXCConfig(t *testing.T) {
|
|
| 23 |
- root, err := ioutil.TempDir("", "TestLXCConfig")
|
|
| 24 |
- if err != nil {
|
|
| 25 |
- t.Fatal(err) |
|
| 26 |
- } |
|
| 27 |
- defer os.RemoveAll(root) |
|
| 28 |
- |
|
| 29 |
- os.MkdirAll(path.Join(root, "containers", "1"), 0777) |
|
| 30 |
- |
|
| 31 |
- // Memory is allocated randomly for testing |
|
| 32 |
- r := rand.New(rand.NewSource(time.Now().UTC().UnixNano())) |
|
| 33 |
- var ( |
|
| 34 |
- memMin = 33554432 |
|
| 35 |
- memMax = 536870912 |
|
| 36 |
- mem = memMin + r.Intn(memMax-memMin) |
|
| 37 |
- swap = memMax |
|
| 38 |
- cpuMin = 100 |
|
| 39 |
- cpuMax = 10000 |
|
| 40 |
- cpu = cpuMin + r.Intn(cpuMax-cpuMin) |
|
| 41 |
- ) |
|
| 42 |
- |
|
| 43 |
- driver, err := NewDriver(root, root, "", false) |
|
| 44 |
- if err != nil {
|
|
| 45 |
- t.Fatal(err) |
|
| 46 |
- } |
|
| 47 |
- command := &execdriver.Command{
|
|
| 48 |
- CommonCommand: execdriver.CommonCommand{
|
|
| 49 |
- ID: "1", |
|
| 50 |
- Network: &execdriver.Network{
|
|
| 51 |
- Mtu: 1500, |
|
| 52 |
- }, |
|
| 53 |
- ProcessConfig: execdriver.ProcessConfig{},
|
|
| 54 |
- Resources: &execdriver.Resources{
|
|
| 55 |
- MemorySwap: int64(swap), |
|
| 56 |
- CommonResources: execdriver.CommonResources{
|
|
| 57 |
- Memory: int64(mem), |
|
| 58 |
- CPUShares: int64(cpu), |
|
| 59 |
- }, |
|
| 60 |
- }, |
|
| 61 |
- }, |
|
| 62 |
- AllowedDevices: make([]*configs.Device, 0), |
|
| 63 |
- } |
|
| 64 |
- p, err := driver.generateLXCConfig(command) |
|
| 65 |
- if err != nil {
|
|
| 66 |
- t.Fatal(err) |
|
| 67 |
- } |
|
| 68 |
- grepFile(t, p, |
|
| 69 |
- fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", mem))
|
|
| 70 |
- |
|
| 71 |
- grepFile(t, p, |
|
| 72 |
- fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", swap))
|
|
| 73 |
-} |
|
| 74 |
- |
|
| 75 |
-func TestCustomLxcConfig(t *testing.T) {
|
|
| 76 |
- root, err := ioutil.TempDir("", "TestCustomLxcConfig")
|
|
| 77 |
- if err != nil {
|
|
| 78 |
- t.Fatal(err) |
|
| 79 |
- } |
|
| 80 |
- defer os.RemoveAll(root) |
|
| 81 |
- |
|
| 82 |
- os.MkdirAll(path.Join(root, "containers", "1"), 0777) |
|
| 83 |
- |
|
| 84 |
- driver, err := NewDriver(root, root, "", false) |
|
| 85 |
- if err != nil {
|
|
| 86 |
- t.Fatal(err) |
|
| 87 |
- } |
|
| 88 |
- processConfig := execdriver.ProcessConfig{
|
|
| 89 |
- Privileged: false, |
|
| 90 |
- } |
|
| 91 |
- command := &execdriver.Command{
|
|
| 92 |
- CommonCommand: execdriver.CommonCommand{
|
|
| 93 |
- ID: "1", |
|
| 94 |
- Network: &execdriver.Network{
|
|
| 95 |
- Mtu: 1500, |
|
| 96 |
- }, |
|
| 97 |
- ProcessConfig: processConfig, |
|
| 98 |
- }, |
|
| 99 |
- LxcConfig: []string{
|
|
| 100 |
- "lxc.utsname = docker", |
|
| 101 |
- "lxc.cgroup.cpuset.cpus = 0,1", |
|
| 102 |
- }, |
|
| 103 |
- } |
|
| 104 |
- |
|
| 105 |
- p, err := driver.generateLXCConfig(command) |
|
| 106 |
- if err != nil {
|
|
| 107 |
- t.Fatal(err) |
|
| 108 |
- } |
|
| 109 |
- |
|
| 110 |
- grepFile(t, p, "lxc.utsname = docker") |
|
| 111 |
- grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") |
|
| 112 |
-} |
|
| 113 |
- |
|
| 114 |
-func grepFile(t *testing.T, path string, pattern string) {
|
|
| 115 |
- grepFileWithReverse(t, path, pattern, false) |
|
| 116 |
-} |
|
| 117 |
- |
|
| 118 |
-func grepFileWithReverse(t *testing.T, path string, pattern string, inverseGrep bool) {
|
|
| 119 |
- f, err := os.Open(path) |
|
| 120 |
- if err != nil {
|
|
| 121 |
- t.Fatal(err) |
|
| 122 |
- } |
|
| 123 |
- defer f.Close() |
|
| 124 |
- r := bufio.NewReader(f) |
|
| 125 |
- var ( |
|
| 126 |
- line string |
|
| 127 |
- ) |
|
| 128 |
- err = nil |
|
| 129 |
- for err == nil {
|
|
| 130 |
- line, err = r.ReadString('\n')
|
|
| 131 |
- if strings.Contains(line, pattern) == true {
|
|
| 132 |
- if inverseGrep {
|
|
| 133 |
- t.Fatalf("grepFile: pattern \"%s\" found in \"%s\"", pattern, path)
|
|
| 134 |
- } |
|
| 135 |
- return |
|
| 136 |
- } |
|
| 137 |
- } |
|
| 138 |
- if inverseGrep {
|
|
| 139 |
- return |
|
| 140 |
- } |
|
| 141 |
- t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
|
|
| 142 |
-} |
|
| 143 |
- |
|
| 144 |
-func TestEscapeFstabSpaces(t *testing.T) {
|
|
| 145 |
- var testInputs = map[string]string{
|
|
| 146 |
- " ": "\\040", |
|
| 147 |
- "": "", |
|
| 148 |
- "/double space": "/double\\040\\040space", |
|
| 149 |
- "/some long test string": "/some\\040long\\040test\\040string", |
|
| 150 |
- "/var/lib/docker": "/var/lib/docker", |
|
| 151 |
- " leading": "\\040leading", |
|
| 152 |
- "trailing ": "trailing\\040", |
|
| 153 |
- } |
|
| 154 |
- for in, exp := range testInputs {
|
|
| 155 |
- if out := escapeFstabSpaces(in); exp != out {
|
|
| 156 |
- t.Logf("Expected %s got %s", exp, out)
|
|
| 157 |
- t.Fail() |
|
| 158 |
- } |
|
| 159 |
- } |
|
| 160 |
-} |
|
| 161 |
- |
|
| 162 |
-func TestIsDirectory(t *testing.T) {
|
|
| 163 |
- tempDir, err := ioutil.TempDir("", "TestIsDir")
|
|
| 164 |
- if err != nil {
|
|
| 165 |
- t.Fatal(err) |
|
| 166 |
- } |
|
| 167 |
- defer os.RemoveAll(tempDir) |
|
| 168 |
- |
|
| 169 |
- tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile") |
|
| 170 |
- if err != nil {
|
|
| 171 |
- t.Fatal(err) |
|
| 172 |
- } |
|
| 173 |
- |
|
| 174 |
- if isDirectory(tempDir) != "dir" {
|
|
| 175 |
- t.Logf("Could not identify %s as a directory", tempDir)
|
|
| 176 |
- t.Fail() |
|
| 177 |
- } |
|
| 178 |
- |
|
| 179 |
- if isDirectory(tempFile.Name()) != "file" {
|
|
| 180 |
- t.Logf("Could not identify %s as a file", tempFile.Name())
|
|
| 181 |
- t.Fail() |
|
| 182 |
- } |
|
| 183 |
-} |
|
| 184 |
- |
|
| 185 |
-func TestCustomLxcConfigMounts(t *testing.T) {
|
|
| 186 |
- root, err := ioutil.TempDir("", "TestCustomLxcConfig")
|
|
| 187 |
- if err != nil {
|
|
| 188 |
- t.Fatal(err) |
|
| 189 |
- } |
|
| 190 |
- defer os.RemoveAll(root) |
|
| 191 |
- tempDir, err := ioutil.TempDir("", "TestIsDir")
|
|
| 192 |
- if err != nil {
|
|
| 193 |
- t.Fatal(err) |
|
| 194 |
- } |
|
| 195 |
- defer os.RemoveAll(tempDir) |
|
| 196 |
- |
|
| 197 |
- tempFile, err := ioutil.TempFile(tempDir, "TestIsDirFile") |
|
| 198 |
- if err != nil {
|
|
| 199 |
- t.Fatal(err) |
|
| 200 |
- } |
|
| 201 |
- os.MkdirAll(path.Join(root, "containers", "1"), 0777) |
|
| 202 |
- |
|
| 203 |
- driver, err := NewDriver(root, root, "", false) |
|
| 204 |
- if err != nil {
|
|
| 205 |
- t.Fatal(err) |
|
| 206 |
- } |
|
| 207 |
- processConfig := execdriver.ProcessConfig{
|
|
| 208 |
- Privileged: false, |
|
| 209 |
- } |
|
| 210 |
- mounts := []execdriver.Mount{
|
|
| 211 |
- {
|
|
| 212 |
- Source: tempDir, |
|
| 213 |
- Destination: tempDir, |
|
| 214 |
- Writable: false, |
|
| 215 |
- Private: true, |
|
| 216 |
- }, |
|
| 217 |
- {
|
|
| 218 |
- Source: tempFile.Name(), |
|
| 219 |
- Destination: tempFile.Name(), |
|
| 220 |
- Writable: true, |
|
| 221 |
- Private: true, |
|
| 222 |
- }, |
|
| 223 |
- } |
|
| 224 |
- command := &execdriver.Command{
|
|
| 225 |
- CommonCommand: execdriver.CommonCommand{
|
|
| 226 |
- ID: "1", |
|
| 227 |
- Network: &execdriver.Network{
|
|
| 228 |
- Mtu: 1500, |
|
| 229 |
- }, |
|
| 230 |
- Mounts: mounts, |
|
| 231 |
- ProcessConfig: processConfig, |
|
| 232 |
- }, |
|
| 233 |
- LxcConfig: []string{
|
|
| 234 |
- "lxc.utsname = docker", |
|
| 235 |
- "lxc.cgroup.cpuset.cpus = 0,1", |
|
| 236 |
- }, |
|
| 237 |
- } |
|
| 238 |
- |
|
| 239 |
- p, err := driver.generateLXCConfig(command) |
|
| 240 |
- if err != nil {
|
|
| 241 |
- t.Fatal(err) |
|
| 242 |
- } |
|
| 243 |
- |
|
| 244 |
- grepFile(t, p, "lxc.utsname = docker") |
|
| 245 |
- grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") |
|
| 246 |
- |
|
| 247 |
- grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,ro,create=%s 0 0", tempDir, "/"+tempDir, "dir"))
|
|
| 248 |
- grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,rw,create=%s 0 0", tempFile.Name(), "/"+tempFile.Name(), "file"))
|
|
| 249 |
-} |
|
| 250 |
- |
|
| 251 |
-func TestCustomLxcConfigMisc(t *testing.T) {
|
|
| 252 |
- root, err := ioutil.TempDir("", "TestCustomLxcConfig")
|
|
| 253 |
- if err != nil {
|
|
| 254 |
- t.Fatal(err) |
|
| 255 |
- } |
|
| 256 |
- defer os.RemoveAll(root) |
|
| 257 |
- os.MkdirAll(path.Join(root, "containers", "1"), 0777) |
|
| 258 |
- driver, err := NewDriver(root, root, "", true) |
|
| 259 |
- |
|
| 260 |
- if err != nil {
|
|
| 261 |
- t.Fatal(err) |
|
| 262 |
- } |
|
| 263 |
- processConfig := execdriver.ProcessConfig{
|
|
| 264 |
- Privileged: false, |
|
| 265 |
- } |
|
| 266 |
- |
|
| 267 |
- processConfig.Env = []string{"HOSTNAME=testhost"}
|
|
| 268 |
- command := &execdriver.Command{
|
|
| 269 |
- CommonCommand: execdriver.CommonCommand{
|
|
| 270 |
- ID: "1", |
|
| 271 |
- Network: &execdriver.Network{
|
|
| 272 |
- Mtu: 1500, |
|
| 273 |
- }, |
|
| 274 |
- ProcessConfig: processConfig, |
|
| 275 |
- }, |
|
| 276 |
- LxcConfig: []string{
|
|
| 277 |
- "lxc.cgroup.cpuset.cpus = 0,1", |
|
| 278 |
- }, |
|
| 279 |
- CapAdd: []string{"net_admin", "syslog"},
|
|
| 280 |
- CapDrop: []string{"kill", "mknod"},
|
|
| 281 |
- AppArmorProfile: "lxc-container-default-with-nesting", |
|
| 282 |
- } |
|
| 283 |
- |
|
| 284 |
- p, err := driver.generateLXCConfig(command) |
|
| 285 |
- if err != nil {
|
|
| 286 |
- t.Fatal(err) |
|
| 287 |
- } |
|
| 288 |
- grepFile(t, p, "lxc.aa_profile = lxc-container-default-with-nesting") |
|
| 289 |
- // hostname |
|
| 290 |
- grepFile(t, p, "lxc.utsname = testhost") |
|
| 291 |
- grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") |
|
| 292 |
- container := nativeTemplate.New() |
|
| 293 |
- for _, cap := range container.Capabilities {
|
|
| 294 |
- realCap := execdriver.GetCapability(cap) |
|
| 295 |
- numCap := fmt.Sprintf("%d", realCap.Value)
|
|
| 296 |
- if cap != "MKNOD" && cap != "KILL" {
|
|
| 297 |
- grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap))
|
|
| 298 |
- } |
|
| 299 |
- } |
|
| 300 |
- |
|
| 301 |
- grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true)
|
|
| 302 |
- grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true)
|
|
| 303 |
-} |
|
| 304 |
- |
|
| 305 |
-func TestCustomLxcConfigMiscOverride(t *testing.T) {
|
|
| 306 |
- root, err := ioutil.TempDir("", "TestCustomLxcConfig")
|
|
| 307 |
- if err != nil {
|
|
| 308 |
- t.Fatal(err) |
|
| 309 |
- } |
|
| 310 |
- defer os.RemoveAll(root) |
|
| 311 |
- os.MkdirAll(path.Join(root, "containers", "1"), 0777) |
|
| 312 |
- driver, err := NewDriver(root, root, "", false) |
|
| 313 |
- if err != nil {
|
|
| 314 |
- t.Fatal(err) |
|
| 315 |
- } |
|
| 316 |
- processConfig := execdriver.ProcessConfig{
|
|
| 317 |
- Privileged: false, |
|
| 318 |
- } |
|
| 319 |
- |
|
| 320 |
- processConfig.Env = []string{"HOSTNAME=testhost"}
|
|
| 321 |
- command := &execdriver.Command{
|
|
| 322 |
- CommonCommand: execdriver.CommonCommand{
|
|
| 323 |
- ID: "1", |
|
| 324 |
- Network: &execdriver.Network{
|
|
| 325 |
- Mtu: 1500, |
|
| 326 |
- }, |
|
| 327 |
- ProcessConfig: processConfig, |
|
| 328 |
- }, |
|
| 329 |
- LxcConfig: []string{
|
|
| 330 |
- "lxc.cgroup.cpuset.cpus = 0,1", |
|
| 331 |
- "lxc.network.ipv4 = 172.0.0.1", |
|
| 332 |
- }, |
|
| 333 |
- CapAdd: []string{"NET_ADMIN", "SYSLOG"},
|
|
| 334 |
- CapDrop: []string{"KILL", "MKNOD"},
|
|
| 335 |
- } |
|
| 336 |
- |
|
| 337 |
- p, err := driver.generateLXCConfig(command) |
|
| 338 |
- if err != nil {
|
|
| 339 |
- t.Fatal(err) |
|
| 340 |
- } |
|
| 341 |
- |
|
| 342 |
- // hostname |
|
| 343 |
- grepFile(t, p, "lxc.utsname = testhost") |
|
| 344 |
- grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1") |
|
| 345 |
- container := nativeTemplate.New() |
|
| 346 |
- for _, cap := range container.Capabilities {
|
|
| 347 |
- realCap := execdriver.GetCapability(cap) |
|
| 348 |
- numCap := fmt.Sprintf("%d", realCap.Value)
|
|
| 349 |
- if cap != "MKNOD" && cap != "KILL" {
|
|
| 350 |
- grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", numCap))
|
|
| 351 |
- } |
|
| 352 |
- } |
|
| 353 |
- grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_KILL), true)
|
|
| 354 |
- grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = %d", capability.CAP_MKNOD), true)
|
|
| 355 |
-} |
| ... | ... |
@@ -1504,7 +1504,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
|
| 1504 | 1504 |
} |
| 1505 | 1505 |
|
| 1506 | 1506 |
// It seems libdevmapper opens this without O_CLOEXEC, and go exec will not close files |
| 1507 |
- // that are not Close-on-exec, and lxc-start will die if it inherits any unexpected files, |
|
| 1507 |
+ // that are not Close-on-exec, |
|
| 1508 | 1508 |
// so we add this badhack to make sure it closes itself |
| 1509 | 1509 |
setCloseOnExec("/dev/mapper/control")
|
| 1510 | 1510 |
|
| ... | ... |
@@ -128,7 +128,6 @@ func (daemon *Daemon) getInspectData(container *Container, size bool) (*types.Co |
| 128 | 128 |
Name: container.Name, |
| 129 | 129 |
RestartCount: container.RestartCount, |
| 130 | 130 |
Driver: container.Driver, |
| 131 |
- ExecDriver: container.ExecDriver, |
|
| 132 | 131 |
MountLabel: container.MountLabel, |
| 133 | 132 |
ProcessLabel: container.ProcessLabel, |
| 134 | 133 |
ExecIDs: container.getExecIDs(), |
| ... | ... |
@@ -2,14 +2,7 @@ |
| 2 | 2 |
|
| 3 | 3 |
package daemon |
| 4 | 4 |
|
| 5 |
-import ( |
|
| 6 |
- "errors" |
|
| 7 |
- "fmt" |
|
| 8 |
- "strings" |
|
| 9 |
- |
|
| 10 |
- "github.com/docker/docker/runconfig" |
|
| 11 |
- "github.com/opencontainers/runc/libcontainer/selinux" |
|
| 12 |
-) |
|
| 5 |
+import "github.com/opencontainers/runc/libcontainer/selinux" |
|
| 13 | 6 |
|
| 14 | 7 |
func selinuxSetDisabled() {
|
| 15 | 8 |
selinux.SetDisabled() |
| ... | ... |
@@ -22,27 +15,3 @@ func selinuxFreeLxcContexts(label string) {
|
| 22 | 22 |
func selinuxEnabled() bool {
|
| 23 | 23 |
return selinux.SelinuxEnabled() |
| 24 | 24 |
} |
| 25 |
- |
|
| 26 |
-func mergeLxcConfIntoOptions(hostConfig *runconfig.HostConfig) ([]string, error) {
|
|
| 27 |
- if hostConfig == nil {
|
|
| 28 |
- return nil, nil |
|
| 29 |
- } |
|
| 30 |
- |
|
| 31 |
- out := []string{}
|
|
| 32 |
- |
|
| 33 |
- // merge in the lxc conf options into the generic config map |
|
| 34 |
- if lxcConf := hostConfig.LxcConf; lxcConf != nil {
|
|
| 35 |
- lxSlice := lxcConf.Slice() |
|
| 36 |
- for _, pair := range lxSlice {
|
|
| 37 |
- // because lxc conf gets the driver name lxc.XXXX we need to trim it off |
|
| 38 |
- // and let the lxc driver add it back later if needed |
|
| 39 |
- if !strings.Contains(pair.Key, ".") {
|
|
| 40 |
- return nil, errors.New("Illegal Key passed into LXC Configurations")
|
|
| 41 |
- } |
|
| 42 |
- parts := strings.SplitN(pair.Key, ".", 2) |
|
| 43 |
- out = append(out, fmt.Sprintf("%s=%s", parts[1], pair.Value))
|
|
| 44 |
- } |
|
| 45 |
- } |
|
| 46 |
- |
|
| 47 |
- return out, nil |
|
| 48 |
-} |
| 49 | 25 |
deleted file mode 100644 |
| ... | ... |
@@ -1,28 +0,0 @@ |
| 1 |
-// +build linux |
|
| 2 |
- |
|
| 3 |
-package daemon |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "testing" |
|
| 7 |
- |
|
| 8 |
- "github.com/docker/docker/runconfig" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-func TestMergeLxcConfig(t *testing.T) {
|
|
| 12 |
- kv := []runconfig.KeyValuePair{
|
|
| 13 |
- {"lxc.cgroups.cpuset", "1,2"},
|
|
| 14 |
- } |
|
| 15 |
- hostConfig := &runconfig.HostConfig{
|
|
| 16 |
- LxcConf: runconfig.NewLxcConfig(kv), |
|
| 17 |
- } |
|
| 18 |
- |
|
| 19 |
- out, err := mergeLxcConfIntoOptions(hostConfig) |
|
| 20 |
- if err != nil {
|
|
| 21 |
- t.Fatalf("Failed to merge Lxc Config: %s", err)
|
|
| 22 |
- } |
|
| 23 |
- |
|
| 24 |
- cpuset := out[0] |
|
| 25 |
- if expected := "cgroups.cpuset=1,2"; cpuset != expected {
|
|
| 26 |
- t.Fatalf("expected %s got %s", expected, cpuset)
|
|
| 27 |
- } |
|
| 28 |
-} |
| ... | ... |
@@ -50,7 +50,6 @@ IRC channel on the Freenode network. |
| 50 | 50 |
| contrib | Yes |Install additional contributed scripts and components.| |
| 51 | 51 |
| device-mapper | Yes |Enables dependencies for the "devicemapper" graph driver, including necessary kernel flags.| |
| 52 | 52 |
| doc | |Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally.| |
| 53 |
-| lxc | |Enables dependencies for the "lxc" execution driver.| |
|
| 54 | 53 |
| vim-syntax | |Pulls in related vim syntax scripts.| |
| 55 | 54 |
| zsh-completion| |Enable zsh completion support.| |
| 56 | 55 |
|
| ... | ... |
@@ -175,7 +175,6 @@ Create a container |
| 175 | 175 |
"HostConfig": {
|
| 176 | 176 |
"Binds": ["/tmp:/tmp"], |
| 177 | 177 |
"Links": ["redis3:redis"], |
| 178 |
- "LxcConf": {"lxc.utsname":"docker"},
|
|
| 179 | 178 |
"Memory": 0, |
| 180 | 179 |
"MemorySwap": 0, |
| 181 | 180 |
"MemoryReservation": 0, |
| ... | ... |
@@ -271,8 +270,6 @@ Json Parameters: |
| 271 | 271 |
+ `volume_name:container_path:ro` to make the bind mount read-only inside the container. |
| 272 | 272 |
- **Links** - A list of links for the container. Each link entry should be |
| 273 | 273 |
in the form of `container_name:alias`. |
| 274 |
- - **LxcConf** - LXC specific configurations. These configurations only |
|
| 275 |
- work when using the `lxc` execution driver. |
|
| 276 | 274 |
- **PortBindings** - A map of exposed container ports and the host port they |
| 277 | 275 |
should map to. A JSON object in the form |
| 278 | 276 |
`{ <port>/<protocol>: [{ "HostPort": "<port>" }] }`
|
| ... | ... |
@@ -676,8 +673,6 @@ Status Codes: |
| 676 | 676 |
|
| 677 | 677 |
This endpoint returns a live stream of a container's resource usage statistics. |
| 678 | 678 |
|
| 679 |
-> **Note**: this functionality currently only works when using the *libcontainer* exec-driver. |
|
| 680 |
- |
|
| 681 | 679 |
**Example request**: |
| 682 | 680 |
|
| 683 | 681 |
GET /containers/redis1/stats HTTP/1.1 |
| ... | ... |
@@ -48,7 +48,6 @@ Creates a new container. |
| 48 | 48 |
--link=[] Add link to another container |
| 49 | 49 |
--log-driver="" Logging driver for container |
| 50 | 50 |
--log-opt=[] Log driver specific options |
| 51 |
- --lxc-conf=[] Add custom lxc options |
|
| 52 | 51 |
-m, --memory="" Memory limit |
| 53 | 52 |
--mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33) |
| 54 | 53 |
--memory-reservation="" Memory soft limit |
| ... | ... |
@@ -29,7 +29,6 @@ weight = -1 |
| 29 | 29 |
--dns-opt=[] DNS options to use |
| 30 | 30 |
--dns-search=[] DNS search domains to use |
| 31 | 31 |
--default-ulimit=[] Set default ulimit settings for containers |
| 32 |
- -e, --exec-driver="native" Exec driver to use |
|
| 33 | 32 |
--exec-opt=[] Set exec driver options |
| 34 | 33 |
--exec-root="/var/run/docker" Root of the Docker execdriver |
| 35 | 34 |
--fixed-cidr="" IPv4 subnet for fixed IPs |
| ... | ... |
@@ -439,11 +438,6 @@ Currently supported options of `zfs`: |
| 439 | 439 |
The Docker daemon uses a specifically built `libcontainer` execution driver as |
| 440 | 440 |
its interface to the Linux kernel `namespaces`, `cgroups`, and `SELinux`. |
| 441 | 441 |
|
| 442 |
-There is still legacy support for the original [LXC userspace tools]( |
|
| 443 |
-https://linuxcontainers.org/) via the `lxc` execution driver, however, this is |
|
| 444 |
-not where the primary development of new functionality is taking place. |
|
| 445 |
-Add `-e lxc` to the daemon flags to use the `lxc` execution driver. |
|
| 446 |
- |
|
| 447 | 442 |
## Options for the native execdriver |
| 448 | 443 |
|
| 449 | 444 |
You can configure the `native` (libcontainer) execdriver using options specified |
| ... | ... |
@@ -47,7 +47,6 @@ parent = "smn_cli" |
| 47 | 47 |
--link=[] Add link to another container |
| 48 | 48 |
--log-driver="" Logging driver for container |
| 49 | 49 |
--log-opt=[] Log driver specific options |
| 50 |
- --lxc-conf=[] Add custom lxc options |
|
| 51 | 50 |
-m, --memory="" Memory limit |
| 52 | 51 |
--mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33) |
| 53 | 52 |
--memory-reservation="" Memory soft limit |
| ... | ... |
@@ -39,7 +39,6 @@ defaults related to: |
| 39 | 39 |
* container identification |
| 40 | 40 |
* network settings |
| 41 | 41 |
* runtime constraints on CPU and memory |
| 42 |
- * privileges and LXC configuration |
|
| 43 | 42 |
|
| 44 | 43 |
With the `docker run [OPTIONS]` an operator can add to or override the |
| 45 | 44 |
image defaults set by a developer. And, additionally, operators can |
| ... | ... |
@@ -75,7 +74,7 @@ following options. |
| 75 | 75 |
- [Restart policies (--restart)](#restart-policies-restart) |
| 76 | 76 |
- [Clean up (--rm)](#clean-up-rm) |
| 77 | 77 |
- [Runtime constraints on resources](#runtime-constraints-on-resources) |
| 78 |
- - [Runtime privilege, Linux capabilities, and LXC configuration](#runtime-privilege-linux-capabilities-and-lxc-configuration) |
|
| 78 |
+ - [Runtime privilege and Linux capabilities](#runtime-privilege-and-linux-capabilities) |
|
| 79 | 79 |
|
| 80 | 80 |
## Detached vs foreground |
| 81 | 81 |
|
| ... | ... |
@@ -965,21 +964,18 @@ one can use this flag: |
| 965 | 965 |
$ docker run -ti --rm --group-add audio --group-add dbus --group-add 777 busybox id |
| 966 | 966 |
uid=0(root) gid=0(root) groups=10(wheel),29(audio),81(dbus),777 |
| 967 | 967 |
|
| 968 |
-## Runtime privilege, Linux capabilities, and LXC configuration |
|
| 968 |
+## Runtime privilege and Linux capabilities |
|
| 969 | 969 |
|
| 970 | 970 |
--cap-add: Add Linux capabilities |
| 971 | 971 |
--cap-drop: Drop Linux capabilities |
| 972 | 972 |
--privileged=false: Give extended privileges to this container |
| 973 | 973 |
--device=[]: Allows you to run devices inside the container without the --privileged flag. |
| 974 |
- --lxc-conf=[]: Add custom lxc options |
|
| 975 | 974 |
|
| 976 | 975 |
By default, Docker containers are "unprivileged" and cannot, for |
| 977 | 976 |
example, run a Docker daemon inside a Docker container. This is because |
| 978 | 977 |
by default a container is not allowed to access any devices, but a |
| 979 |
-"privileged" container is given access to all devices (see [lxc-template.go]( |
|
| 980 |
-https://github.com/docker/docker/blob/master/daemon/execdriver/lxc/lxc_template.go) |
|
| 981 |
-and documentation on [cgroups devices]( |
|
| 982 |
-https://www.kernel.org/doc/Documentation/cgroups/devices.txt)). |
|
| 978 |
+"privileged" container is given access to all devices (see |
|
| 979 |
+the documentation on [cgroups devices](https://www.kernel.org/doc/Documentation/cgroups/devices.txt)). |
|
| 983 | 980 |
|
| 984 | 981 |
When the operator executes `docker run --privileged`, Docker will enable |
| 985 | 982 |
to access to all devices on the host as well as set some configuration |
| ... | ... |
@@ -1093,22 +1089,6 @@ To mount a FUSE based filesystem, you need to combine both `--cap-add` and |
| 1093 | 1093 |
.... |
| 1094 | 1094 |
|
| 1095 | 1095 |
|
| 1096 |
-If the Docker daemon was started using the `lxc` exec-driver |
|
| 1097 |
-(`docker daemon --exec-driver=lxc`) then the operator can also specify LXC options |
|
| 1098 |
-using one or more `--lxc-conf` parameters. These can be new parameters or |
|
| 1099 |
-override existing parameters from the [lxc-template.go]( |
|
| 1100 |
-https://github.com/docker/docker/blob/master/daemon/execdriver/lxc/lxc_template.go). |
|
| 1101 |
-Note that in the future, a given host's docker daemon may not use LXC, so this |
|
| 1102 |
-is an implementation-specific configuration meant for operators already |
|
| 1103 |
-familiar with using LXC directly. |
|
| 1104 |
- |
|
| 1105 |
-> **Note:** |
|
| 1106 |
-> If you use `--lxc-conf` to modify a container's configuration which is also |
|
| 1107 |
-> managed by the Docker daemon, then the Docker daemon will not know about this |
|
| 1108 |
-> modification, and you will need to manage any conflicts yourself. For example, |
|
| 1109 |
-> you can use `--lxc-conf` to set a container's IP address, but this will not be |
|
| 1110 |
-> reflected in the `/etc/hosts` file. |
|
| 1111 |
- |
|
| 1112 | 1096 |
## Logging drivers (--log-driver) |
| 1113 | 1097 |
|
| 1114 | 1098 |
The container can have a different logging driver than the Docker daemon. Use |
| ... | ... |
@@ -1290,7 +1270,6 @@ above, or already defined by the developer with a Dockerfile `ENV`: |
| 1290 | 1290 |
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
| 1291 | 1291 |
declare -x PWD="/" |
| 1292 | 1292 |
declare -x SHLVL="1" |
| 1293 |
- declare -x container="lxc" |
|
| 1294 | 1293 |
declare -x deep="purple" |
| 1295 | 1294 |
|
| 1296 | 1295 |
Similarly the operator can set the **hostname** with `-h`. |
| ... | ... |
@@ -109,7 +109,6 @@ running a Docker daemon with experimental user namespaces enabled: |
| 109 | 109 |
- A `--readonly` container filesystem (a Linux kernel restriction on remount with new flags of a currently mounted filesystem when inside a user namespace) |
| 110 | 110 |
- external (volume/graph) drivers which are unaware/incapable of using daemon user mappings |
| 111 | 111 |
- Using `--privileged` mode containers |
| 112 |
- - Using the lxc execdriver (only the `native` execdriver is enabled to use user namespaces) |
|
| 113 | 112 |
- volume use without pre-arranging proper file ownership in mounted volumes |
| 114 | 113 |
|
| 115 | 114 |
Additionally, while the `root` user inside a user namespaced container |
| ... | ... |
@@ -31,13 +31,6 @@ if ! mountpoint -q /sys/fs/cgroup; then |
| 31 | 31 |
# Mount the cgroup hierarchies exactly as they are in the parent system. |
| 32 | 32 |
for HIER in $(cut -d: -f2 /proc/1/cgroup); do |
| 33 | 33 |
|
| 34 |
- # The following sections address a bug which manifests itself |
|
| 35 |
- # by a cryptic "lxc-start: no ns_cgroup option specified" when |
|
| 36 |
- # trying to start containers within a container. |
|
| 37 |
- # The bug seems to appear when the cgroup hierarchies are not |
|
| 38 |
- # mounted on the exact same directories in the host, and in the |
|
| 39 |
- # container. |
|
| 40 |
- |
|
| 41 | 34 |
SUBSYSTEMS="${HIER%name=*}"
|
| 42 | 35 |
|
| 43 | 36 |
# If cgroup hierarchy is named(mounted with "-o name=foo") we |
| ... | ... |
@@ -109,10 +109,6 @@ if [ -z "$DOCKER_CLIENTONLY" ]; then |
| 109 | 109 |
fi |
| 110 | 110 |
fi |
| 111 | 111 |
|
| 112 |
-if [ "$DOCKER_EXECDRIVER" = 'lxc' ]; then |
|
| 113 |
- DOCKER_BUILDTAGS+=' test_no_exec' |
|
| 114 |
-fi |
|
| 115 |
- |
|
| 116 | 112 |
# test whether "btrfs/version.h" exists and apply btrfs_noversion appropriately |
| 117 | 113 |
if \ |
| 118 | 114 |
command -v gcc &> /dev/null \ |
| ... | ... |
@@ -13,7 +13,6 @@ fi |
| 13 | 13 |
exec 41>&1 42>&2 |
| 14 | 14 |
|
| 15 | 15 |
export DOCKER_GRAPHDRIVER=${DOCKER_GRAPHDRIVER:-vfs}
|
| 16 |
-export DOCKER_EXECDRIVER=${DOCKER_EXECDRIVER:-native}
|
|
| 17 | 16 |
export DOCKER_USERLANDPROXY=${DOCKER_USERLANDPROXY:-true}
|
| 18 | 17 |
|
| 19 | 18 |
# example usage: DOCKER_STORAGE_OPTS="dm.basesize=20G,dm.loopdatasize=200G" |
| ... | ... |
@@ -49,7 +48,6 @@ if [ -z "$DOCKER_TEST_HOST" ]; then |
| 49 | 49 |
docker daemon --debug \ |
| 50 | 50 |
--host "$DOCKER_HOST" \ |
| 51 | 51 |
--storage-driver "$DOCKER_GRAPHDRIVER" \ |
| 52 |
- --exec-driver "$DOCKER_EXECDRIVER" \ |
|
| 53 | 52 |
--pidfile "$DEST/docker.pid" \ |
| 54 | 53 |
--userland-proxy="$DOCKER_USERLANDPROXY" \ |
| 55 | 54 |
$storage_params \ |
| ... | ... |
@@ -27,7 +27,6 @@ func (s *DockerSuite) TestExecResizeApiHeightWidthNoInt(c *check.C) {
|
| 27 | 27 |
// Part of #14845 |
| 28 | 28 |
func (s *DockerSuite) TestExecResizeImmediatelyAfterExecStart(c *check.C) {
|
| 29 | 29 |
testRequires(c, DaemonIsLinux) |
| 30 |
- testRequires(c, NativeExecDriver) |
|
| 31 | 30 |
|
| 32 | 31 |
name := "exec_resize_test" |
| 33 | 32 |
dockerCmd(c, "run", "-d", "-i", "-t", "--name", name, "--restart", "always", "busybox", "/bin/sh") |
| ... | ... |
@@ -18,7 +18,7 @@ func (s *DockerSuite) TestInspectApiContainerResponse(c *check.C) {
|
| 18 | 18 |
|
| 19 | 19 |
cleanedContainerID := strings.TrimSpace(out) |
| 20 | 20 |
keysBase := []string{"Id", "State", "Created", "Path", "Args", "Config", "Image", "NetworkSettings",
|
| 21 |
- "ResolvConfPath", "HostnamePath", "HostsPath", "LogPath", "Name", "Driver", "ExecDriver", "MountLabel", "ProcessLabel", "GraphDriver"} |
|
| 21 |
+ "ResolvConfPath", "HostnamePath", "HostsPath", "LogPath", "Name", "Driver", "MountLabel", "ProcessLabel", "GraphDriver"} |
|
| 22 | 22 |
|
| 23 | 23 |
cases := []struct {
|
| 24 | 24 |
version string |
| ... | ... |
@@ -5459,7 +5459,6 @@ func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
|
| 5459 | 5459 |
} |
| 5460 | 5460 |
|
| 5461 | 5461 |
func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
|
| 5462 |
- testRequires(c, NativeExecDriver) |
|
| 5463 | 5462 |
testRequires(c, SameHostDaemon) |
| 5464 | 5463 |
testRequires(c, DaemonIsLinux) |
| 5465 | 5464 |
|
| ... | ... |
@@ -870,7 +870,7 @@ func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4ExplicitOutsideContainer |
| 870 | 870 |
} |
| 871 | 871 |
|
| 872 | 872 |
func (s *DockerDaemonSuite) TestDaemonDefaultNetworkInvalidClusterConfig(c *check.C) {
|
| 873 |
- testRequires(c, SameHostDaemon) |
|
| 873 |
+ testRequires(c, DaemonIsLinux, SameHostDaemon) |
|
| 874 | 874 |
|
| 875 | 875 |
// Start daemon without docker0 bridge |
| 876 | 876 |
defaultNetworkBridge := "docker0" |
| ... | ... |
@@ -1032,7 +1032,7 @@ func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *che |
| 1032 | 1032 |
} |
| 1033 | 1033 |
|
| 1034 | 1034 |
func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) {
|
| 1035 |
- testRequires(c, NativeExecDriver) |
|
| 1035 |
+ testRequires(c, DaemonIsLinux) |
|
| 1036 | 1036 |
|
| 1037 | 1037 |
if err := s.d.StartWithBusybox("--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024"); err != nil {
|
| 1038 | 1038 |
c.Fatal(err) |
| ... | ... |
@@ -1527,7 +1527,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterCrash(c *check.C) {
|
| 1527 | 1527 |
} |
| 1528 | 1528 |
|
| 1529 | 1529 |
func (s *DockerDaemonSuite) TestRunContainerWithBridgeNone(c *check.C) {
|
| 1530 |
- testRequires(c, NativeExecDriver, NotUserNamespace) |
|
| 1530 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 1531 | 1531 |
c.Assert(s.d.StartWithBusybox("-b", "none"), check.IsNil)
|
| 1532 | 1532 |
|
| 1533 | 1533 |
out, err := s.d.Cmd("run", "--rm", "busybox", "ip", "l")
|
| ... | ... |
@@ -58,8 +58,8 @@ func (s *DockerSuite) TestDiffEnsureOnlyKmsgAndPtmx(c *check.C) {
|
| 58 | 58 |
"C /dev": true, |
| 59 | 59 |
"A /dev/full": true, // busybox |
| 60 | 60 |
"C /dev/ptmx": true, // libcontainer |
| 61 |
- "A /dev/mqueue": true, // lxc |
|
| 62 |
- "A /dev/kmsg": true, // lxc |
|
| 61 |
+ "A /dev/mqueue": true, |
|
| 62 |
+ "A /dev/kmsg": true, |
|
| 63 | 63 |
"A /dev/fd": true, |
| 64 | 64 |
"A /dev/fuse": true, |
| 65 | 65 |
"A /dev/ptmx": true, |
| ... | ... |
@@ -47,7 +47,6 @@ func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) {
|
| 47 | 47 |
|
| 48 | 48 |
func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) {
|
| 49 | 49 |
testRequires(c, DaemonIsLinux) |
| 50 |
- testRequires(c, NativeExecDriver) |
|
| 51 | 50 |
testRequires(c, oomControl) |
| 52 | 51 |
testRequires(c, NotGCCGO) |
| 53 | 52 |
|
| ... | ... |
@@ -84,7 +83,6 @@ func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) {
|
| 84 | 84 |
|
| 85 | 85 |
func (s *DockerSuite) TestEventsOOMDisableTrue(c *check.C) {
|
| 86 | 86 |
testRequires(c, DaemonIsLinux) |
| 87 |
- testRequires(c, NativeExecDriver) |
|
| 88 | 87 |
testRequires(c, oomControl) |
| 89 | 88 |
testRequires(c, NotGCCGO) |
| 90 | 89 |
|
| ... | ... |
@@ -32,8 +32,7 @@ func (s *DockerSuite) TestExperimentalVersion(c *check.C) {
|
| 32 | 32 |
// 1. validate uid/gid maps are set properly |
| 33 | 33 |
// 2. verify that files created are owned by remapped root |
| 34 | 34 |
func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) {
|
| 35 |
- testRequires(c, NativeExecDriver) |
|
| 36 |
- testRequires(c, SameHostDaemon) |
|
| 35 |
+ testRequires(c, DaemonIsLinux, SameHostDaemon) |
|
| 37 | 36 |
|
| 38 | 37 |
c.Assert(s.d.StartWithBusybox("--userns-remap", "default"), checker.IsNil)
|
| 39 | 38 |
|
| ... | ... |
@@ -50,8 +50,7 @@ func getContainerStatus(c *check.C, containerID string) string {
|
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 | 52 |
func (s *DockerSuite) TestNetworkNat(c *check.C) {
|
| 53 |
- testRequires(c, DaemonIsLinux) |
|
| 54 |
- testRequires(c, SameHostDaemon, NativeExecDriver) |
|
| 53 |
+ testRequires(c, DaemonIsLinux, SameHostDaemon) |
|
| 55 | 54 |
msg := "it works" |
| 56 | 55 |
startServerContainer(c, msg, 8080) |
| 57 | 56 |
endpoint := getExternalAddress(c) |
| ... | ... |
@@ -67,8 +66,7 @@ func (s *DockerSuite) TestNetworkNat(c *check.C) {
|
| 67 | 67 |
} |
| 68 | 68 |
|
| 69 | 69 |
func (s *DockerSuite) TestNetworkLocalhostTCPNat(c *check.C) {
|
| 70 |
- testRequires(c, DaemonIsLinux) |
|
| 71 |
- testRequires(c, SameHostDaemon, NativeExecDriver) |
|
| 70 |
+ testRequires(c, DaemonIsLinux, SameHostDaemon) |
|
| 72 | 71 |
var ( |
| 73 | 72 |
msg = "hi yall" |
| 74 | 73 |
) |
| ... | ... |
@@ -85,8 +83,7 @@ func (s *DockerSuite) TestNetworkLocalhostTCPNat(c *check.C) {
|
| 85 | 85 |
} |
| 86 | 86 |
|
| 87 | 87 |
func (s *DockerSuite) TestNetworkLoopbackNat(c *check.C) {
|
| 88 |
- testRequires(c, DaemonIsLinux) |
|
| 89 |
- testRequires(c, SameHostDaemon, NativeExecDriver, NotUserNamespace) |
|
| 88 |
+ testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace) |
|
| 90 | 89 |
msg := "it works" |
| 91 | 90 |
startServerContainer(c, msg, 8080) |
| 92 | 91 |
endpoint := getExternalAddress(c) |
| ... | ... |
@@ -66,13 +66,11 @@ func (s *DockerSuite) TestRunLookupGoogleDns(c *check.C) {
|
| 66 | 66 |
} |
| 67 | 67 |
|
| 68 | 68 |
// the exit code should be 0 |
| 69 |
-// some versions of lxc might make this test fail |
|
| 70 | 69 |
func (s *DockerSuite) TestRunExitCodeZero(c *check.C) {
|
| 71 | 70 |
dockerCmd(c, "run", "busybox", "true") |
| 72 | 71 |
} |
| 73 | 72 |
|
| 74 | 73 |
// the exit code should be 1 |
| 75 |
-// some versions of lxc might make this test fail |
|
| 76 | 74 |
func (s *DockerSuite) TestRunExitCodeOne(c *check.C) {
|
| 77 | 75 |
_, exitCode, err := dockerCmdWithError("run", "busybox", "false")
|
| 78 | 76 |
if err != nil && !strings.Contains("exit status 1", fmt.Sprintf("%s", err)) {
|
| ... | ... |
@@ -84,7 +82,6 @@ func (s *DockerSuite) TestRunExitCodeOne(c *check.C) {
|
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 | 86 |
// it should be possible to pipe in data via stdin to a process running in a container |
| 87 |
-// some versions of lxc might make this test fail |
|
| 88 | 87 |
func (s *DockerSuite) TestRunStdinPipe(c *check.C) {
|
| 89 | 88 |
// TODO Windows: This needs some work to make compatible. |
| 90 | 89 |
testRequires(c, DaemonIsLinux) |
| ... | ... |
@@ -262,7 +259,7 @@ func (s *DockerSuite) TestRunCreateVolumesInSymlinkDir(c *check.C) {
|
| 262 | 262 |
if daemonPlatform == "windows" {
|
| 263 | 263 |
testRequires(c, SameHostDaemon, WindowsDaemonSupportsVolumes) |
| 264 | 264 |
} else {
|
| 265 |
- testRequires(c, SameHostDaemon, NativeExecDriver) |
|
| 265 |
+ testRequires(c, SameHostDaemon) |
|
| 266 | 266 |
} |
| 267 | 267 |
|
| 268 | 268 |
name := "test-volume-symlink" |
| ... | ... |
@@ -664,7 +661,7 @@ func (s *DockerSuite) TestRunTwoConcurrentContainers(c *check.C) {
|
| 664 | 664 |
|
| 665 | 665 |
func (s *DockerSuite) TestRunEnvironment(c *check.C) {
|
| 666 | 666 |
// TODO Windows: Environment handling is different between Linux and |
| 667 |
- // Windows and this test relies currently on lxc and unix functionality. |
|
| 667 |
+ // Windows and this test relies currently on unix functionality. |
|
| 668 | 668 |
testRequires(c, DaemonIsLinux) |
| 669 | 669 |
cmd := exec.Command(dockerBinary, "run", "-h", "testing", "-e=FALSE=true", "-e=TRUE", "-e=TRICKY", "-e=HOME=", "busybox", "env") |
| 670 | 670 |
cmd.Env = append(os.Environ(), |
| ... | ... |
@@ -677,13 +674,7 @@ func (s *DockerSuite) TestRunEnvironment(c *check.C) {
|
| 677 | 677 |
c.Fatal(err, out) |
| 678 | 678 |
} |
| 679 | 679 |
|
| 680 |
- actualEnvLxc := strings.Split(strings.TrimSpace(out), "\n") |
|
| 681 |
- actualEnv := []string{}
|
|
| 682 |
- for i := range actualEnvLxc {
|
|
| 683 |
- if actualEnvLxc[i] != "container=lxc" {
|
|
| 684 |
- actualEnv = append(actualEnv, actualEnvLxc[i]) |
|
| 685 |
- } |
|
| 686 |
- } |
|
| 680 |
+ actualEnv := strings.Split(strings.TrimSpace(out), "\n") |
|
| 687 | 681 |
sort.Strings(actualEnv) |
| 688 | 682 |
|
| 689 | 683 |
goodEnv := []string{
|
| ... | ... |
@@ -709,7 +700,7 @@ func (s *DockerSuite) TestRunEnvironment(c *check.C) {
|
| 709 | 709 |
|
| 710 | 710 |
func (s *DockerSuite) TestRunEnvironmentErase(c *check.C) {
|
| 711 | 711 |
// TODO Windows: Environment handling is different between Linux and |
| 712 |
- // Windows and this test relies currently on lxc and unix functionality. |
|
| 712 |
+ // Windows and this test relies currently on unix functionality. |
|
| 713 | 713 |
testRequires(c, DaemonIsLinux) |
| 714 | 714 |
|
| 715 | 715 |
// Test to make sure that when we use -e on env vars that are |
| ... | ... |
@@ -724,13 +715,7 @@ func (s *DockerSuite) TestRunEnvironmentErase(c *check.C) {
|
| 724 | 724 |
c.Fatal(err, out) |
| 725 | 725 |
} |
| 726 | 726 |
|
| 727 |
- actualEnvLxc := strings.Split(strings.TrimSpace(out), "\n") |
|
| 728 |
- actualEnv := []string{}
|
|
| 729 |
- for i := range actualEnvLxc {
|
|
| 730 |
- if actualEnvLxc[i] != "container=lxc" {
|
|
| 731 |
- actualEnv = append(actualEnv, actualEnvLxc[i]) |
|
| 732 |
- } |
|
| 733 |
- } |
|
| 727 |
+ actualEnv := strings.Split(strings.TrimSpace(out), "\n") |
|
| 734 | 728 |
sort.Strings(actualEnv) |
| 735 | 729 |
|
| 736 | 730 |
goodEnv := []string{
|
| ... | ... |
@@ -750,7 +735,7 @@ func (s *DockerSuite) TestRunEnvironmentErase(c *check.C) {
|
| 750 | 750 |
|
| 751 | 751 |
func (s *DockerSuite) TestRunEnvironmentOverride(c *check.C) {
|
| 752 | 752 |
// TODO Windows: Environment handling is different between Linux and |
| 753 |
- // Windows and this test relies currently on lxc and unix functionality. |
|
| 753 |
+ // Windows and this test relies currently on unix functionality. |
|
| 754 | 754 |
testRequires(c, DaemonIsLinux) |
| 755 | 755 |
|
| 756 | 756 |
// Test to make sure that when we use -e on env vars that are |
| ... | ... |
@@ -764,13 +749,7 @@ func (s *DockerSuite) TestRunEnvironmentOverride(c *check.C) {
|
| 764 | 764 |
c.Fatal(err, out) |
| 765 | 765 |
} |
| 766 | 766 |
|
| 767 |
- actualEnvLxc := strings.Split(strings.TrimSpace(out), "\n") |
|
| 768 |
- actualEnv := []string{}
|
|
| 769 |
- for i := range actualEnvLxc {
|
|
| 770 |
- if actualEnvLxc[i] != "container=lxc" {
|
|
| 771 |
- actualEnv = append(actualEnv, actualEnvLxc[i]) |
|
| 772 |
- } |
|
| 773 |
- } |
|
| 767 |
+ actualEnv := strings.Split(strings.TrimSpace(out), "\n") |
|
| 774 | 768 |
sort.Strings(actualEnv) |
| 775 | 769 |
|
| 776 | 770 |
goodEnv := []string{
|
| ... | ... |
@@ -944,7 +923,7 @@ func (s *DockerSuite) TestRunCapAddALLDropNetAdminCanDownInterface(c *check.C) {
|
| 944 | 944 |
|
| 945 | 945 |
func (s *DockerSuite) TestRunGroupAdd(c *check.C) {
|
| 946 | 946 |
// Not applicable for Windows as there is no concept of --group-add |
| 947 |
- testRequires(c, DaemonIsLinux, NativeExecDriver) |
|
| 947 |
+ testRequires(c, DaemonIsLinux) |
|
| 948 | 948 |
out, _ := dockerCmd(c, "run", "--group-add=audio", "--group-add=staff", "--group-add=777", "busybox", "sh", "-c", "id") |
| 949 | 949 |
|
| 950 | 950 |
groupsList := "uid=0(root) gid=0(root) groups=10(wheel),29(audio),50(staff),777" |
| ... | ... |
@@ -1301,7 +1280,7 @@ func (s *DockerSuite) TestRunNonRootUserResolvName(c *check.C) {
|
| 1301 | 1301 |
// uses the host's /etc/resolv.conf and does not have any dns options provided. |
| 1302 | 1302 |
func (s *DockerSuite) TestRunResolvconfUpdate(c *check.C) {
|
| 1303 | 1303 |
// Not applicable on Windows as testing unix specific functionality |
| 1304 |
- testRequires(c, SameHostDaemon, DaemonIsLinux, NativeExecDriver) |
|
| 1304 |
+ testRequires(c, SameHostDaemon, DaemonIsLinux) |
|
| 1305 | 1305 |
|
| 1306 | 1306 |
tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\n")
|
| 1307 | 1307 |
tmpLocalhostResolvConf := []byte("nameserver 127.0.0.1")
|
| ... | ... |
@@ -2261,9 +2240,6 @@ func (s *DockerSuite) TestRunExposePort(c *check.C) {
|
| 2261 | 2261 |
} |
| 2262 | 2262 |
|
| 2263 | 2263 |
func (s *DockerSuite) TestRunUnknownCommand(c *check.C) {
|
| 2264 |
- if daemonPlatform != "windows" {
|
|
| 2265 |
- testRequires(c, NativeExecDriver) |
|
| 2266 |
- } |
|
| 2267 | 2264 |
out, _, _ := dockerCmdWithStdoutStderr(c, "create", "busybox", "/bin/nada") |
| 2268 | 2265 |
|
| 2269 | 2266 |
cID := strings.TrimSpace(out) |
| ... | ... |
@@ -2405,7 +2381,7 @@ func (s *DockerSuite) TestContainerNetworkMode(c *check.C) {
|
| 2405 | 2405 |
|
| 2406 | 2406 |
func (s *DockerSuite) TestRunModePidHost(c *check.C) {
|
| 2407 | 2407 |
// Not applicable on Windows as uses Unix-specific capabilities |
| 2408 |
- testRequires(c, NativeExecDriver, SameHostDaemon, DaemonIsLinux, NotUserNamespace) |
|
| 2408 |
+ testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace) |
|
| 2409 | 2409 |
|
| 2410 | 2410 |
hostPid, err := os.Readlink("/proc/1/ns/pid")
|
| 2411 | 2411 |
if err != nil {
|
| ... | ... |
@@ -2427,7 +2403,7 @@ func (s *DockerSuite) TestRunModePidHost(c *check.C) {
|
| 2427 | 2427 |
|
| 2428 | 2428 |
func (s *DockerSuite) TestRunModeUTSHost(c *check.C) {
|
| 2429 | 2429 |
// Not applicable on Windows as uses Unix-specific capabilities |
| 2430 |
- testRequires(c, NativeExecDriver, SameHostDaemon, DaemonIsLinux) |
|
| 2430 |
+ testRequires(c, SameHostDaemon, DaemonIsLinux) |
|
| 2431 | 2431 |
|
| 2432 | 2432 |
hostUTS, err := os.Readlink("/proc/1/ns/uts")
|
| 2433 | 2433 |
if err != nil {
|
| ... | ... |
@@ -2657,7 +2633,7 @@ func (s *DockerSuite) TestRunContainerWithWritableRootfs(c *check.C) {
|
| 2657 | 2657 |
|
| 2658 | 2658 |
func (s *DockerSuite) TestRunContainerWithReadonlyRootfs(c *check.C) {
|
| 2659 | 2659 |
// Not applicable on Windows which does not support --read-only |
| 2660 |
- testRequires(c, NativeExecDriver, DaemonIsLinux) |
|
| 2660 |
+ testRequires(c, DaemonIsLinux) |
|
| 2661 | 2661 |
|
| 2662 | 2662 |
for _, f := range []string{"/file", "/etc/hosts", "/etc/resolv.conf", "/etc/hostname", "/sys/kernel", "/dev/.dont.touch.me"} {
|
| 2663 | 2663 |
testReadOnlyFile(f, c) |
| ... | ... |
@@ -2668,7 +2644,7 @@ func (s *DockerSuite) TestPermissionsPtsReadonlyRootfs(c *check.C) {
|
| 2668 | 2668 |
// Not applicable on Windows due to use of Unix specific functionality, plus |
| 2669 | 2669 |
// the use of --read-only which is not supported. |
| 2670 | 2670 |
// --read-only + userns has remount issues |
| 2671 |
- testRequires(c, DaemonIsLinux, NativeExecDriver, NotUserNamespace) |
|
| 2671 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 2672 | 2672 |
|
| 2673 | 2673 |
// Ensure we have not broken writing /dev/pts |
| 2674 | 2674 |
out, status := dockerCmd(c, "run", "--read-only", "--rm", "busybox", "mount") |
| ... | ... |
@@ -2683,7 +2659,7 @@ func (s *DockerSuite) TestPermissionsPtsReadonlyRootfs(c *check.C) {
|
| 2683 | 2683 |
|
| 2684 | 2684 |
func testReadOnlyFile(filename string, c *check.C) {
|
| 2685 | 2685 |
// Not applicable on Windows which does not support --read-only |
| 2686 |
- testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace) |
|
| 2686 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 2687 | 2687 |
|
| 2688 | 2688 |
out, _, err := dockerCmdWithError("run", "--read-only", "--rm", "busybox", "touch", filename)
|
| 2689 | 2689 |
if err == nil {
|
| ... | ... |
@@ -2707,7 +2683,7 @@ func testReadOnlyFile(filename string, c *check.C) {
|
| 2707 | 2707 |
func (s *DockerSuite) TestRunContainerWithReadonlyEtcHostsAndLinkedContainer(c *check.C) {
|
| 2708 | 2708 |
// Not applicable on Windows which does not support --link |
| 2709 | 2709 |
// --read-only + userns has remount issues |
| 2710 |
- testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace) |
|
| 2710 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 2711 | 2711 |
|
| 2712 | 2712 |
dockerCmd(c, "run", "-d", "--name", "test-etc-hosts-ro-linked", "busybox", "top") |
| 2713 | 2713 |
|
| ... | ... |
@@ -2720,7 +2696,7 @@ func (s *DockerSuite) TestRunContainerWithReadonlyEtcHostsAndLinkedContainer(c * |
| 2720 | 2720 |
func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithDnsFlag(c *check.C) {
|
| 2721 | 2721 |
// Not applicable on Windows which does not support either --read-only or --dns. |
| 2722 | 2722 |
// --read-only + userns has remount issues |
| 2723 |
- testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace) |
|
| 2723 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 2724 | 2724 |
|
| 2725 | 2725 |
out, _ := dockerCmd(c, "run", "--read-only", "--dns", "1.1.1.1", "busybox", "/bin/cat", "/etc/resolv.conf") |
| 2726 | 2726 |
if !strings.Contains(string(out), "1.1.1.1") {
|
| ... | ... |
@@ -2731,7 +2707,7 @@ func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithDnsFlag(c *check.C) |
| 2731 | 2731 |
func (s *DockerSuite) TestRunContainerWithReadonlyRootfsWithAddHostFlag(c *check.C) {
|
| 2732 | 2732 |
// Not applicable on Windows which does not support --read-only |
| 2733 | 2733 |
// --read-only + userns has remount issues |
| 2734 |
- testRequires(c, NativeExecDriver, DaemonIsLinux, NotUserNamespace) |
|
| 2734 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 2735 | 2735 |
|
| 2736 | 2736 |
out, _ := dockerCmd(c, "run", "--read-only", "--add-host", "testreadonly:127.0.0.1", "busybox", "/bin/cat", "/etc/hosts") |
| 2737 | 2737 |
if !strings.Contains(string(out), "testreadonly") {
|
| ... | ... |
@@ -2836,7 +2812,7 @@ func (s *DockerSuite) TestRunWriteToProcAsound(c *check.C) {
|
| 2836 | 2836 |
|
| 2837 | 2837 |
func (s *DockerSuite) TestRunReadProcTimer(c *check.C) {
|
| 2838 | 2838 |
// Not applicable on Windows as uses Unix specific functionality |
| 2839 |
- testRequires(c, NativeExecDriver, DaemonIsLinux) |
|
| 2839 |
+ testRequires(c, DaemonIsLinux) |
|
| 2840 | 2840 |
out, code, err := dockerCmdWithError("run", "busybox", "cat", "/proc/timer_stats")
|
| 2841 | 2841 |
if code != 0 {
|
| 2842 | 2842 |
return |
| ... | ... |
@@ -2851,7 +2827,7 @@ func (s *DockerSuite) TestRunReadProcTimer(c *check.C) {
|
| 2851 | 2851 |
|
| 2852 | 2852 |
func (s *DockerSuite) TestRunReadProcLatency(c *check.C) {
|
| 2853 | 2853 |
// Not applicable on Windows as uses Unix specific functionality |
| 2854 |
- testRequires(c, NativeExecDriver, DaemonIsLinux) |
|
| 2854 |
+ testRequires(c, DaemonIsLinux) |
|
| 2855 | 2855 |
// some kernels don't have this configured so skip the test if this file is not found |
| 2856 | 2856 |
// on the host running the tests. |
| 2857 | 2857 |
if _, err := os.Stat("/proc/latency_stats"); err != nil {
|
| ... | ... |
@@ -2896,7 +2872,6 @@ func (s *DockerSuite) TestRunReadFilteredProc(c *check.C) {
|
| 2896 | 2896 |
func (s *DockerSuite) TestMountIntoProc(c *check.C) {
|
| 2897 | 2897 |
// Not applicable on Windows as uses Unix specific functionality |
| 2898 | 2898 |
testRequires(c, DaemonIsLinux) |
| 2899 |
- testRequires(c, NativeExecDriver) |
|
| 2900 | 2899 |
_, code, err := dockerCmdWithError("run", "-v", "/proc//sys", "busybox", "true")
|
| 2901 | 2900 |
if err == nil || code == 0 {
|
| 2902 | 2901 |
c.Fatal("container should not be able to mount into /proc")
|
| ... | ... |
@@ -2906,7 +2881,7 @@ func (s *DockerSuite) TestMountIntoProc(c *check.C) {
|
| 2906 | 2906 |
func (s *DockerSuite) TestMountIntoSys(c *check.C) {
|
| 2907 | 2907 |
// Not applicable on Windows as uses Unix specific functionality |
| 2908 | 2908 |
testRequires(c, DaemonIsLinux) |
| 2909 |
- testRequires(c, NativeExecDriver, NotUserNamespace) |
|
| 2909 |
+ testRequires(c, NotUserNamespace) |
|
| 2910 | 2910 |
dockerCmd(c, "run", "-v", "/sys/fs/cgroup", "busybox", "true") |
| 2911 | 2911 |
} |
| 2912 | 2912 |
|
| ... | ... |
@@ -2914,7 +2889,7 @@ func (s *DockerSuite) TestRunUnshareProc(c *check.C) {
|
| 2914 | 2914 |
c.Skip("unstable test: is apparmor in a container reliable?")
|
| 2915 | 2915 |
|
| 2916 | 2916 |
// Not applicable on Windows as uses Unix specific functionality |
| 2917 |
- testRequires(c, Apparmor, NativeExecDriver, DaemonIsLinux) |
|
| 2917 |
+ testRequires(c, Apparmor, DaemonIsLinux) |
|
| 2918 | 2918 |
|
| 2919 | 2919 |
name := "acidburn" |
| 2920 | 2920 |
if out, _, err := dockerCmdWithError("run", "--name", name, "jess/unshare", "unshare", "-p", "-m", "-f", "-r", "--mount-proc=/proc", "mount"); err == nil || !strings.Contains(out, "Permission denied") {
|
| ... | ... |
@@ -2948,7 +2923,6 @@ func (s *DockerSuite) TestRunPublishPort(c *check.C) {
|
| 2948 | 2948 |
func (s *DockerSuite) TestDevicePermissions(c *check.C) {
|
| 2949 | 2949 |
// Not applicable on Windows as uses Unix specific functionality |
| 2950 | 2950 |
testRequires(c, DaemonIsLinux) |
| 2951 |
- testRequires(c, NativeExecDriver) |
|
| 2952 | 2951 |
const permissions = "crw-rw-rw-" |
| 2953 | 2952 |
out, status := dockerCmd(c, "run", "--device", "/dev/fuse:/dev/fuse:mrw", "busybox:latest", "ls", "-l", "/dev/fuse") |
| 2954 | 2953 |
if status != 0 {
|
| ... | ... |
@@ -2962,7 +2936,6 @@ func (s *DockerSuite) TestDevicePermissions(c *check.C) {
|
| 2962 | 2962 |
func (s *DockerSuite) TestRunCapAddCHOWN(c *check.C) {
|
| 2963 | 2963 |
// Not applicable on Windows as uses Unix specific functionality |
| 2964 | 2964 |
testRequires(c, DaemonIsLinux) |
| 2965 |
- testRequires(c, NativeExecDriver) |
|
| 2966 | 2965 |
out, _ := dockerCmd(c, "run", "--cap-drop=ALL", "--cap-add=CHOWN", "busybox", "sh", "-c", "adduser -D -H newuser && chown newuser /home && echo ok") |
| 2967 | 2966 |
|
| 2968 | 2967 |
if actual := strings.Trim(out, "\r\n"); actual != "ok" {
|
| ... | ... |
@@ -3005,7 +2978,7 @@ func (s *DockerSuite) TestVolumeFromMixedRWOptions(c *check.C) {
|
| 3005 | 3005 |
|
| 3006 | 3006 |
func (s *DockerSuite) TestRunWriteFilteredProc(c *check.C) {
|
| 3007 | 3007 |
// Not applicable on Windows as uses Unix specific functionality |
| 3008 |
- testRequires(c, Apparmor, NativeExecDriver, DaemonIsLinux, NotUserNamespace) |
|
| 3008 |
+ testRequires(c, Apparmor, DaemonIsLinux, NotUserNamespace) |
|
| 3009 | 3009 |
|
| 3010 | 3010 |
testWritePaths := []string{
|
| 3011 | 3011 |
/* modprobe and core_pattern should both be denied by generic |
| ... | ... |
@@ -3274,7 +3247,7 @@ func (s *DockerSuite) TestPtraceContainerProcsFromHost(c *check.C) {
|
| 3274 | 3274 |
|
| 3275 | 3275 |
func (s *DockerSuite) TestAppArmorDeniesPtrace(c *check.C) {
|
| 3276 | 3276 |
// Not applicable on Windows as uses Unix specific functionality |
| 3277 |
- testRequires(c, SameHostDaemon, NativeExecDriver, Apparmor, DaemonIsLinux, NotGCCGO) |
|
| 3277 |
+ testRequires(c, SameHostDaemon, Apparmor, DaemonIsLinux, NotGCCGO) |
|
| 3278 | 3278 |
|
| 3279 | 3279 |
// Run through 'sh' so we are NOT pid 1. Pid 1 may be able to trace |
| 3280 | 3280 |
// itself, but pid>1 should not be able to trace pid1. |
| ... | ... |
@@ -3298,7 +3271,7 @@ func (s *DockerSuite) TestAppArmorDeniesChmodProc(c *check.C) {
|
| 3298 | 3298 |
c.Skip("Test is failing, and what it tests is unclear")
|
| 3299 | 3299 |
|
| 3300 | 3300 |
// Not applicable on Windows as uses Unix specific functionality |
| 3301 |
- testRequires(c, SameHostDaemon, NativeExecDriver, Apparmor, DaemonIsLinux) |
|
| 3301 |
+ testRequires(c, SameHostDaemon, Apparmor, DaemonIsLinux) |
|
| 3302 | 3302 |
_, exitCode, _ := dockerCmdWithError("run", "busybox", "chmod", "744", "/proc/cpuinfo")
|
| 3303 | 3303 |
if exitCode == 0 {
|
| 3304 | 3304 |
// If our test failed, attempt to repair the host system... |
| ... | ... |
@@ -3311,7 +3284,7 @@ func (s *DockerSuite) TestAppArmorDeniesChmodProc(c *check.C) {
|
| 3311 | 3311 |
|
| 3312 | 3312 |
func (s *DockerSuite) TestRunCapAddSYSTIME(c *check.C) {
|
| 3313 | 3313 |
// Not applicable on Windows as uses Unix specific functionality |
| 3314 |
- testRequires(c, DaemonIsLinux, NativeExecDriver) |
|
| 3314 |
+ testRequires(c, DaemonIsLinux) |
|
| 3315 | 3315 |
|
| 3316 | 3316 |
dockerCmd(c, "run", "--cap-drop=ALL", "--cap-add=SYS_TIME", "busybox", "sh", "-c", "grep ^CapEff /proc/self/status | sed 's/^CapEff:\t//' | grep ^0000000002000000$") |
| 3317 | 3317 |
} |
| ... | ... |
@@ -3348,7 +3321,7 @@ func (s *DockerSuite) TestRunNamedVolume(c *check.C) {
|
| 3348 | 3348 |
|
| 3349 | 3349 |
func (s *DockerSuite) TestRunWithUlimits(c *check.C) {
|
| 3350 | 3350 |
// Not applicable on Windows as uses Unix specific functionality |
| 3351 |
- testRequires(c, DaemonIsLinux, NativeExecDriver) |
|
| 3351 |
+ testRequires(c, DaemonIsLinux) |
|
| 3352 | 3352 |
|
| 3353 | 3353 |
out, _ := dockerCmd(c, "run", "--name=testulimits", "--ulimit", "nofile=42", "busybox", "/bin/sh", "-c", "ulimit -n") |
| 3354 | 3354 |
ul := strings.TrimSpace(out) |
| ... | ... |
@@ -3359,7 +3332,7 @@ func (s *DockerSuite) TestRunWithUlimits(c *check.C) {
|
| 3359 | 3359 |
|
| 3360 | 3360 |
func (s *DockerSuite) TestRunContainerWithCgroupParent(c *check.C) {
|
| 3361 | 3361 |
// Not applicable on Windows as uses Unix specific functionality |
| 3362 |
- testRequires(c, DaemonIsLinux, NativeExecDriver) |
|
| 3362 |
+ testRequires(c, DaemonIsLinux) |
|
| 3363 | 3363 |
|
| 3364 | 3364 |
cgroupParent := "test" |
| 3365 | 3365 |
name := "cgroup-test" |
| ... | ... |
@@ -3389,7 +3362,7 @@ func (s *DockerSuite) TestRunContainerWithCgroupParent(c *check.C) {
|
| 3389 | 3389 |
|
| 3390 | 3390 |
func (s *DockerSuite) TestRunContainerWithCgroupParentAbsPath(c *check.C) {
|
| 3391 | 3391 |
// Not applicable on Windows as uses Unix specific functionality |
| 3392 |
- testRequires(c, DaemonIsLinux, NativeExecDriver) |
|
| 3392 |
+ testRequires(c, DaemonIsLinux) |
|
| 3393 | 3393 |
|
| 3394 | 3394 |
cgroupParent := "/cgroup-parent/test" |
| 3395 | 3395 |
name := "cgroup-test" |
| ... | ... |
@@ -3419,7 +3392,7 @@ func (s *DockerSuite) TestRunContainerWithCgroupParentAbsPath(c *check.C) {
|
| 3419 | 3419 |
func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
|
| 3420 | 3420 |
// Not applicable on Windows as uses Unix specific functionality |
| 3421 | 3421 |
// --read-only + userns has remount issues |
| 3422 |
- testRequires(c, DaemonIsLinux, NativeExecDriver, NotUserNamespace) |
|
| 3422 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 3423 | 3423 |
|
| 3424 | 3424 |
filename := "/sys/fs/cgroup/devices/test123" |
| 3425 | 3425 |
out, _, err := dockerCmdWithError("run", "busybox", "touch", filename)
|
| ... | ... |
@@ -3574,7 +3547,7 @@ func (s *DockerSuite) TestContainersInUserDefinedNetwork(c *check.C) {
|
| 3574 | 3574 |
} |
| 3575 | 3575 |
|
| 3576 | 3576 |
func (s *DockerSuite) TestContainersInMultipleNetworks(c *check.C) {
|
| 3577 |
- testRequires(c, DaemonIsLinux, NotUserNamespace, NativeExecDriver) |
|
| 3577 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 3578 | 3578 |
// Create 2 networks using bridge driver |
| 3579 | 3579 |
dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1") |
| 3580 | 3580 |
dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2") |
| ... | ... |
@@ -3593,7 +3566,7 @@ func (s *DockerSuite) TestContainersInMultipleNetworks(c *check.C) {
|
| 3593 | 3593 |
} |
| 3594 | 3594 |
|
| 3595 | 3595 |
func (s *DockerSuite) TestContainersNetworkIsolation(c *check.C) {
|
| 3596 |
- testRequires(c, DaemonIsLinux, NotUserNamespace, NativeExecDriver) |
|
| 3596 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 3597 | 3597 |
// Create 2 networks using bridge driver |
| 3598 | 3598 |
dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1") |
| 3599 | 3599 |
dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2") |
| ... | ... |
@@ -3638,7 +3611,7 @@ func (s *DockerSuite) TestNetworkRmWithActiveContainers(c *check.C) {
|
| 3638 | 3638 |
} |
| 3639 | 3639 |
|
| 3640 | 3640 |
func (s *DockerSuite) TestContainerRestartInMultipleNetworks(c *check.C) {
|
| 3641 |
- testRequires(c, DaemonIsLinux, NotUserNamespace, NativeExecDriver) |
|
| 3641 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 3642 | 3642 |
// Create 2 networks using bridge driver |
| 3643 | 3643 |
dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork1") |
| 3644 | 3644 |
dockerCmd(c, "network", "create", "-d", "bridge", "testnetwork2") |
| ... | ... |
@@ -17,7 +17,6 @@ import ( |
| 17 | 17 |
"github.com/docker/docker/pkg/mount" |
| 18 | 18 |
"github.com/docker/docker/pkg/parsers" |
| 19 | 19 |
"github.com/docker/docker/pkg/sysinfo" |
| 20 |
- "github.com/docker/docker/pkg/units" |
|
| 21 | 20 |
"github.com/go-check/check" |
| 22 | 21 |
"github.com/kr/pty" |
| 23 | 22 |
) |
| ... | ... |
@@ -93,7 +92,7 @@ func (s *DockerSuite) TestRunWithVolumesIsRecursive(c *check.C) {
|
| 93 | 93 |
} |
| 94 | 94 |
|
| 95 | 95 |
func (s *DockerSuite) TestRunDeviceDirectory(c *check.C) {
|
| 96 |
- testRequires(c, NativeExecDriver, NotUserNamespace) |
|
| 96 |
+ testRequires(c, DaemonIsLinux, NotUserNamespace) |
|
| 97 | 97 |
if _, err := os.Stat("/dev/snd"); err != nil {
|
| 98 | 98 |
c.Skip("Host does not have /dev/snd")
|
| 99 | 99 |
} |
| ... | ... |
@@ -315,7 +314,7 @@ func (s *DockerSuite) TestRunEchoStdoutWithMemoryLimit(c *check.C) {
|
| 315 | 315 |
// 16M memory and as much swap memory as they need (if the host |
| 316 | 316 |
// supports swap memory). |
| 317 | 317 |
func (s *DockerSuite) TestRunWithoutMemoryswapLimit(c *check.C) {
|
| 318 |
- testRequires(c, NativeExecDriver) |
|
| 318 |
+ testRequires(c, DaemonIsLinux) |
|
| 319 | 319 |
testRequires(c, memoryLimitSupport) |
| 320 | 320 |
testRequires(c, swapMemorySupport) |
| 321 | 321 |
dockerCmd(c, "run", "-m", "16m", "--memory-swap", "-1", "busybox", "true") |
| ... | ... |
@@ -425,7 +424,7 @@ func (s *DockerSuite) TestRunInvalidCpusetMemsFlagValue(c *check.C) {
|
| 425 | 425 |
} |
| 426 | 426 |
|
| 427 | 427 |
func (s *DockerSuite) TestRunInvalidCPUShares(c *check.C) {
|
| 428 |
- testRequires(c, cpuShare, NativeExecDriver) |
|
| 428 |
+ testRequires(c, cpuShare, DaemonIsLinux) |
|
| 429 | 429 |
out, _, err := dockerCmdWithError("run", "--cpu-shares", "1", "busybox", "echo", "test")
|
| 430 | 430 |
c.Assert(err, check.NotNil, check.Commentf(out)) |
| 431 | 431 |
expected := "The minimum allowed cpu-shares is 2" |
| ... | ... |
@@ -441,22 +440,3 @@ func (s *DockerSuite) TestRunInvalidCPUShares(c *check.C) {
|
| 441 | 441 |
expected = "The maximum allowed cpu-shares is" |
| 442 | 442 |
c.Assert(out, checker.Contains, expected) |
| 443 | 443 |
} |
| 444 |
- |
|
| 445 |
-func (s *DockerSuite) TestRunWithCorrectMemorySwapOnLXC(c *check.C) {
|
|
| 446 |
- testRequires(c, memoryLimitSupport) |
|
| 447 |
- testRequires(c, swapMemorySupport) |
|
| 448 |
- testRequires(c, SameHostDaemon) |
|
| 449 |
- |
|
| 450 |
- out, _ := dockerCmd(c, "run", "-d", "-m", "32m", "--memory-swap", "64m", "busybox", "top") |
|
| 451 |
- if _, err := os.Stat("/sys/fs/cgroup/memory/lxc"); err != nil {
|
|
| 452 |
- c.Skip("Excecution driver must be LXC for this test")
|
|
| 453 |
- } |
|
| 454 |
- id := strings.TrimSpace(out) |
|
| 455 |
- memorySwap, err := ioutil.ReadFile(fmt.Sprintf("/sys/fs/cgroup/memory/lxc/%s/memory.memsw.limit_in_bytes", id))
|
|
| 456 |
- c.Assert(err, check.IsNil) |
|
| 457 |
- cgSwap, err := strconv.ParseInt(strings.TrimSpace(string(memorySwap)), 10, 64) |
|
| 458 |
- c.Assert(err, check.IsNil) |
|
| 459 |
- swap, err := units.RAMInBytes("64m")
|
|
| 460 |
- c.Assert(err, check.IsNil) |
|
| 461 |
- c.Assert(cgSwap, check.Equals, swap) |
|
| 462 |
-} |
| ... | ... |
@@ -229,9 +229,6 @@ func (d *Daemon) Start(arg ...string) error {
|
| 229 | 229 |
if d.storageDriver != "" {
|
| 230 | 230 |
args = append(args, "--storage-driver", d.storageDriver) |
| 231 | 231 |
} |
| 232 |
- if d.execDriver != "" {
|
|
| 233 |
- args = append(args, "--exec-driver", d.execDriver) |
|
| 234 |
- } |
|
| 235 | 232 |
|
| 236 | 233 |
args = append(args, arg...) |
| 237 | 234 |
d.cmd = exec.Command(dockerBinary, args...) |
| ... | ... |
@@ -1,10 +1,8 @@ |
| 1 | 1 |
package main |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "encoding/json" |
|
| 5 | 4 |
"fmt" |
| 6 | 5 |
"io/ioutil" |
| 7 |
- "log" |
|
| 8 | 6 |
"net/http" |
| 9 | 7 |
"os" |
| 10 | 8 |
"os/exec" |
| ... | ... |
@@ -23,8 +21,6 @@ type testRequirement struct {
|
| 23 | 23 |
|
| 24 | 24 |
// List test requirements |
| 25 | 25 |
var ( |
| 26 |
- daemonExecDriver string |
|
| 27 |
- |
|
| 28 | 26 |
DaemonIsWindows = testRequirement{
|
| 29 | 27 |
func() bool { return daemonPlatform == "windows" },
|
| 30 | 28 |
"Test requires a Windows daemon", |
| ... | ... |
@@ -105,30 +101,6 @@ var ( |
| 105 | 105 |
}, |
| 106 | 106 |
fmt.Sprintf("Test requires an environment that can host %s in the same host", notaryBinary),
|
| 107 | 107 |
} |
| 108 |
- NativeExecDriver = testRequirement{
|
|
| 109 |
- func() bool {
|
|
| 110 |
- if daemonExecDriver == "" {
|
|
| 111 |
- // get daemon info |
|
| 112 |
- status, body, err := sockRequest("GET", "/info", nil)
|
|
| 113 |
- if err != nil || status != http.StatusOK {
|
|
| 114 |
- log.Fatalf("sockRequest failed for /info: %v", err)
|
|
| 115 |
- } |
|
| 116 |
- |
|
| 117 |
- type infoJSON struct {
|
|
| 118 |
- ExecutionDriver string |
|
| 119 |
- } |
|
| 120 |
- var info infoJSON |
|
| 121 |
- if err = json.Unmarshal(body, &info); err != nil {
|
|
| 122 |
- log.Fatalf("unable to unmarshal body: %v", err)
|
|
| 123 |
- } |
|
| 124 |
- |
|
| 125 |
- daemonExecDriver = info.ExecutionDriver |
|
| 126 |
- } |
|
| 127 |
- |
|
| 128 |
- return strings.HasPrefix(daemonExecDriver, "native") |
|
| 129 |
- }, |
|
| 130 |
- "Test requires the native (libcontainer) exec driver.", |
|
| 131 |
- } |
|
| 132 | 108 |
NotOverlay = testRequirement{
|
| 133 | 109 |
func() bool {
|
| 134 | 110 |
cmd := exec.Command("grep", "^overlay / overlay", "/proc/mounts")
|
| ... | ... |
@@ -37,7 +37,6 @@ docker-create - Create a new container |
| 37 | 37 |
[**--link**[=*[]*]] |
| 38 | 38 |
[**--log-driver**[=*[]*]] |
| 39 | 39 |
[**--log-opt**[=*[]*]] |
| 40 |
-[**--lxc-conf**[=*[]*]] |
|
| 41 | 40 |
[**-m**|**--memory**[=*MEMORY*]] |
| 42 | 41 |
[**--mac-address**[=*MAC-ADDRESS*]] |
| 43 | 42 |
[**--memory-reservation**[=*MEMORY-RESERVATION*]] |
| ... | ... |
@@ -182,9 +181,6 @@ millions of trillions. |
| 182 | 182 |
**--log-opt**=[] |
| 183 | 183 |
Logging driver specific options. |
| 184 | 184 |
|
| 185 |
-**--lxc-conf**=[] |
|
| 186 |
- (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1" |
|
| 187 |
- |
|
| 188 | 185 |
**-m**, **--memory**="" |
| 189 | 186 |
Memory limit (format: <number>[<unit>], where unit = b, k, m or g) |
| 190 | 187 |
|
| ... | ... |
@@ -20,7 +20,6 @@ docker-daemon - Enable daemon mode |
| 20 | 20 |
[**--dns**[=*[]*]] |
| 21 | 21 |
[**--dns-opt**[=*[]*]] |
| 22 | 22 |
[**--dns-search**[=*[]*]] |
| 23 |
-[**-e**|**--exec-driver**[=*native*]] |
|
| 24 | 23 |
[**--exec-opt**[=*[]*]] |
| 25 | 24 |
[**--exec-root**[=*/var/run/docker*]] |
| 26 | 25 |
[**--fixed-cidr**[=*FIXED-CIDR*]] |
| ... | ... |
@@ -112,9 +111,6 @@ format. |
| 112 | 112 |
**--dns-search**=[] |
| 113 | 113 |
DNS search domains to use. |
| 114 | 114 |
|
| 115 |
-**-e**, **--exec-driver**="" |
|
| 116 |
- Force Docker to use specific exec driver. Default is `native`. |
|
| 117 |
- |
|
| 118 | 115 |
**--exec-opt**=[] |
| 119 | 116 |
Set exec driver options. See EXEC DRIVER OPTIONS. |
| 120 | 117 |
|
| ... | ... |
@@ -38,7 +38,6 @@ docker-run - Run a command in a new container |
| 38 | 38 |
[**--link**[=*[]*]] |
| 39 | 39 |
[**--log-driver**[=*[]*]] |
| 40 | 40 |
[**--log-opt**[=*[]*]] |
| 41 |
-[**--lxc-conf**[=*[]*]] |
|
| 42 | 41 |
[**-m**|**--memory**[=*MEMORY*]] |
| 43 | 42 |
[**--mac-address**[=*MAC-ADDRESS*]] |
| 44 | 43 |
[**--memory-reservation**[=*MEMORY-RESERVATION*]] |
| ... | ... |
@@ -274,9 +273,6 @@ container can access the exposed port via a private networking interface. Docker |
| 274 | 274 |
will set some environment variables in the client container to help indicate |
| 275 | 275 |
which interface and port to use. |
| 276 | 276 |
|
| 277 |
-**--lxc-conf**=[] |
|
| 278 |
- (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1" |
|
| 279 |
- |
|
| 280 | 277 |
**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*awslogs*|*splunk*|*none*" |
| 281 | 278 |
Logging driver for container. Default is defined by daemon `--log-driver` flag. |
| 282 | 279 |
**Warning**: the `docker logs` command works only for the `json-file` and |
| ... | ... |
@@ -225,8 +225,8 @@ inside it) |
| 225 | 225 |
|
| 226 | 226 |
# EXEC DRIVER OPTIONS |
| 227 | 227 |
|
| 228 |
-Use the **--exec-opt** flags to specify options to the exec-driver. The only |
|
| 229 |
-driver that accepts this flag is the *native* (libcontainer) driver. As a |
|
| 228 |
+Use the **--exec-opt** flags to specify options to the execution driver. The only |
|
| 229 |
+runtime that accepts any options is Linux. As a |
|
| 230 | 230 |
result, you must also specify **-s=**native for this option to have effect. The |
| 231 | 231 |
following is the only *native* option: |
| 232 | 232 |
|
| ... | ... |
@@ -298,7 +298,6 @@ the client will even run on alternative platforms such as Mac OS X / Darwin. |
| 298 | 298 |
Some of Docker's features are activated by using optional command-line flags or |
| 299 | 299 |
by having support for them in the kernel or userspace. A few examples include: |
| 300 | 300 |
|
| 301 |
-* LXC execution driver (requires version 1.0.7 or later of lxc and the lxc-libs) |
|
| 302 | 301 |
* AUFS graph driver (requires AUFS patches/support enabled in the kernel, and at |
| 303 | 302 |
least the "auplink" utility from aufs-tools) |
| 304 | 303 |
* BTRFS graph driver (requires BTRFS support enabled in the kernel) |
| ... | ... |
@@ -24,7 +24,7 @@ type NetworkMode string |
| 24 | 24 |
type IsolationLevel string |
| 25 | 25 |
|
| 26 | 26 |
// IsDefault indicates the default isolation level of a container. On Linux this |
| 27 |
-// is LXC. On Windows, this is a Windows Server Container. |
|
| 27 |
+// is the native driver. On Windows, this is a Windows Server Container. |
|
| 28 | 28 |
func (i IsolationLevel) IsDefault() bool {
|
| 29 | 29 |
return strings.ToLower(string(i)) == "default" || string(i) == "" |
| 30 | 30 |
} |
| ... | ... |
@@ -164,69 +164,12 @@ type LogConfig struct {
|
| 164 | 164 |
Config map[string]string |
| 165 | 165 |
} |
| 166 | 166 |
|
| 167 |
-// LxcConfig represents the specific LXC configuration of the container. |
|
| 168 |
-type LxcConfig struct {
|
|
| 169 |
- values []KeyValuePair |
|
| 170 |
-} |
|
| 171 |
- |
|
| 172 |
-// MarshalJSON marshals (or serializes) the LxcConfig into JSON. |
|
| 173 |
-func (c *LxcConfig) MarshalJSON() ([]byte, error) {
|
|
| 174 |
- if c == nil {
|
|
| 175 |
- return []byte{}, nil
|
|
| 176 |
- } |
|
| 177 |
- return json.Marshal(c.Slice()) |
|
| 178 |
-} |
|
| 179 |
- |
|
| 180 |
-// UnmarshalJSON unmarshals (or deserializes) the specified byte slices from JSON to |
|
| 181 |
-// a LxcConfig. |
|
| 182 |
-func (c *LxcConfig) UnmarshalJSON(b []byte) error {
|
|
| 183 |
- if len(b) == 0 {
|
|
| 184 |
- return nil |
|
| 185 |
- } |
|
| 186 |
- |
|
| 187 |
- var kv []KeyValuePair |
|
| 188 |
- if err := json.Unmarshal(b, &kv); err != nil {
|
|
| 189 |
- var h map[string]string |
|
| 190 |
- if err := json.Unmarshal(b, &h); err != nil {
|
|
| 191 |
- return err |
|
| 192 |
- } |
|
| 193 |
- for k, v := range h {
|
|
| 194 |
- kv = append(kv, KeyValuePair{k, v})
|
|
| 195 |
- } |
|
| 196 |
- } |
|
| 197 |
- c.values = kv |
|
| 198 |
- |
|
| 199 |
- return nil |
|
| 200 |
-} |
|
| 201 |
- |
|
| 202 |
-// Len returns the number of specific lxc configuration. |
|
| 203 |
-func (c *LxcConfig) Len() int {
|
|
| 204 |
- if c == nil {
|
|
| 205 |
- return 0 |
|
| 206 |
- } |
|
| 207 |
- return len(c.values) |
|
| 208 |
-} |
|
| 209 |
- |
|
| 210 |
-// Slice returns the specific lxc configuration into a slice of KeyValuePair. |
|
| 211 |
-func (c *LxcConfig) Slice() []KeyValuePair {
|
|
| 212 |
- if c == nil {
|
|
| 213 |
- return nil |
|
| 214 |
- } |
|
| 215 |
- return c.values |
|
| 216 |
-} |
|
| 217 |
- |
|
| 218 |
-// NewLxcConfig creates a LxcConfig from the specified slice of KeyValuePair. |
|
| 219 |
-func NewLxcConfig(values []KeyValuePair) *LxcConfig {
|
|
| 220 |
- return &LxcConfig{values}
|
|
| 221 |
-} |
|
| 222 |
- |
|
| 223 | 167 |
// HostConfig the non-portable Config structure of a container. |
| 224 | 168 |
// Here, "non-portable" means "dependent of the host we are running on". |
| 225 | 169 |
// Portable information *should* appear in Config. |
| 226 | 170 |
type HostConfig struct {
|
| 227 | 171 |
Binds []string // List of volume bindings for this container |
| 228 | 172 |
ContainerIDFile string // File (path) where the containerId is written |
| 229 |
- LxcConf *LxcConfig // Additional lxc configuration |
|
| 230 | 173 |
Memory int64 // Memory limit (in bytes) |
| 231 | 174 |
MemoryReservation int64 // Memory soft limit (in bytes) |
| 232 | 175 |
MemorySwap int64 // Total memory usage (memory + swap); set `-1` to disable swap |
| ... | ... |
@@ -162,53 +162,6 @@ func TestRestartPolicy(t *testing.T) {
|
| 162 | 162 |
} |
| 163 | 163 |
} |
| 164 | 164 |
|
| 165 |
-func TestLxcConfigMarshalJSON(t *testing.T) {
|
|
| 166 |
- lxcConfigs := map[*LxcConfig]string{
|
|
| 167 |
- nil: "", |
|
| 168 |
- &LxcConfig{}: "null",
|
|
| 169 |
- &LxcConfig{
|
|
| 170 |
- []KeyValuePair{{"key1", "value1"}},
|
|
| 171 |
- }: `[{"Key":"key1","Value":"value1"}]`,
|
|
| 172 |
- } |
|
| 173 |
- |
|
| 174 |
- for lxcconfig, expected := range lxcConfigs {
|
|
| 175 |
- data, err := lxcconfig.MarshalJSON() |
|
| 176 |
- if err != nil {
|
|
| 177 |
- t.Fatal(err) |
|
| 178 |
- } |
|
| 179 |
- if string(data) != expected {
|
|
| 180 |
- t.Fatalf("Expected %v, got %v", expected, string(data))
|
|
| 181 |
- } |
|
| 182 |
- } |
|
| 183 |
-} |
|
| 184 |
- |
|
| 185 |
-func TestLxcConfigUnmarshalJSON(t *testing.T) {
|
|
| 186 |
- keyvaluePairs := map[string][]KeyValuePair{
|
|
| 187 |
- "": {{"key1", "value1"}},
|
|
| 188 |
- "[]": {},
|
|
| 189 |
- `[{"Key":"key2","Value":"value2"}]`: {{"key2", "value2"}},
|
|
| 190 |
- } |
|
| 191 |
- for json, expectedParts := range keyvaluePairs {
|
|
| 192 |
- lxcConfig := &LxcConfig{
|
|
| 193 |
- []KeyValuePair{{"key1", "value1"}},
|
|
| 194 |
- } |
|
| 195 |
- if err := lxcConfig.UnmarshalJSON([]byte(json)); err != nil {
|
|
| 196 |
- t.Fatal(err) |
|
| 197 |
- } |
|
| 198 |
- |
|
| 199 |
- actualParts := lxcConfig.Slice() |
|
| 200 |
- if len(actualParts) != len(expectedParts) {
|
|
| 201 |
- t.Fatalf("Expected %v keyvaluePairs, got %v (%v)", len(expectedParts), len(actualParts), expectedParts)
|
|
| 202 |
- } |
|
| 203 |
- for index, part := range actualParts {
|
|
| 204 |
- if part != expectedParts[index] {
|
|
| 205 |
- t.Fatalf("Expected %v, got %v", expectedParts, actualParts)
|
|
| 206 |
- break |
|
| 207 |
- } |
|
| 208 |
- } |
|
| 209 |
- } |
|
| 210 |
-} |
|
| 211 |
- |
|
| 212 | 165 |
func TestMergeConfigs(t *testing.T) {
|
| 213 | 166 |
expectedHostname := "hostname" |
| 214 | 167 |
expectedContainerIDFile := "containerIdFile" |
| ... | ... |
@@ -62,7 +62,6 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 62 | 62 |
flDNSOptions = opts.NewListOpts(nil) |
| 63 | 63 |
flExtraHosts = opts.NewListOpts(opts.ValidateExtraHost) |
| 64 | 64 |
flVolumesFrom = opts.NewListOpts(nil) |
| 65 |
- flLxcOpts = opts.NewListOpts(nil) |
|
| 66 | 65 |
flEnvFile = opts.NewListOpts(nil) |
| 67 | 66 |
flCapAdd = opts.NewListOpts(nil) |
| 68 | 67 |
flCapDrop = opts.NewListOpts(nil) |
| ... | ... |
@@ -121,7 +120,6 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 121 | 121 |
cmd.Var(&flDNSOptions, []string{"-dns-opt"}, "Set DNS options")
|
| 122 | 122 |
cmd.Var(&flExtraHosts, []string{"-add-host"}, "Add a custom host-to-IP mapping (host:ip)")
|
| 123 | 123 |
cmd.Var(&flVolumesFrom, []string{"#volumes-from", "-volumes-from"}, "Mount volumes from the specified container(s)")
|
| 124 |
- cmd.Var(&flLxcOpts, []string{"#lxc-conf", "-lxc-conf"}, "Add custom lxc options")
|
|
| 125 | 124 |
cmd.Var(&flCapAdd, []string{"-cap-add"}, "Add Linux capabilities")
|
| 126 | 125 |
cmd.Var(&flCapDrop, []string{"-cap-drop"}, "Drop Linux capabilities")
|
| 127 | 126 |
cmd.Var(&flGroupAdd, []string{"-group-add"}, "Add additional groups to join")
|
| ... | ... |
@@ -223,12 +221,6 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 223 | 223 |
entrypoint = stringutils.NewStrSlice(*flEntrypoint) |
| 224 | 224 |
} |
| 225 | 225 |
|
| 226 |
- lc, err := parseKeyValueOpts(flLxcOpts) |
|
| 227 |
- if err != nil {
|
|
| 228 |
- return nil, nil, cmd, err |
|
| 229 |
- } |
|
| 230 |
- lxcConf := NewLxcConfig(lc) |
|
| 231 |
- |
|
| 232 | 226 |
var ( |
| 233 | 227 |
domainname string |
| 234 | 228 |
hostname = *flHostname |
| ... | ... |
@@ -340,7 +332,6 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 340 | 340 |
hostConfig := &HostConfig{
|
| 341 | 341 |
Binds: binds, |
| 342 | 342 |
ContainerIDFile: *flContainerIDFile, |
| 343 |
- LxcConf: lxcConf, |
|
| 344 | 343 |
Memory: flMemory, |
| 345 | 344 |
MemoryReservation: MemoryReservation, |
| 346 | 345 |
MemorySwap: memorySwap, |
| ... | ... |
@@ -12,7 +12,6 @@ import ( |
| 12 | 12 |
|
| 13 | 13 |
flag "github.com/docker/docker/pkg/mflag" |
| 14 | 14 |
"github.com/docker/docker/pkg/nat" |
| 15 |
- "github.com/docker/docker/pkg/parsers" |
|
| 16 | 15 |
) |
| 17 | 16 |
|
| 18 | 17 |
func parseRun(args []string) (*Config, *HostConfig, *flag.FlagSet, error) {
|
| ... | ... |
@@ -344,35 +343,6 @@ func setupPlatformVolume(u []string, w []string) ([]string, string) {
|
| 344 | 344 |
return a, s |
| 345 | 345 |
} |
| 346 | 346 |
|
| 347 |
-func TestParseLxcConfOpt(t *testing.T) {
|
|
| 348 |
- opts := []string{"lxc.utsname=docker", "lxc.utsname = docker "}
|
|
| 349 |
- |
|
| 350 |
- for _, o := range opts {
|
|
| 351 |
- k, v, err := parsers.ParseKeyValueOpt(o) |
|
| 352 |
- if err != nil {
|
|
| 353 |
- t.FailNow() |
|
| 354 |
- } |
|
| 355 |
- if k != "lxc.utsname" {
|
|
| 356 |
- t.Fail() |
|
| 357 |
- } |
|
| 358 |
- if v != "docker" {
|
|
| 359 |
- t.Fail() |
|
| 360 |
- } |
|
| 361 |
- } |
|
| 362 |
- |
|
| 363 |
- // With parseRun too |
|
| 364 |
- _, hostconfig, _, err := parseRun([]string{"lxc.utsname=docker", "lxc.utsname = docker ", "img", "cmd"})
|
|
| 365 |
- if err != nil {
|
|
| 366 |
- t.Fatal(err) |
|
| 367 |
- } |
|
| 368 |
- for _, lxcConf := range hostconfig.LxcConf.Slice() {
|
|
| 369 |
- if lxcConf.Key != "lxc.utsname" || lxcConf.Value != "docker" {
|
|
| 370 |
- t.Fail() |
|
| 371 |
- } |
|
| 372 |
- } |
|
| 373 |
- |
|
| 374 |
-} |
|
| 375 |
- |
|
| 376 | 347 |
// Simple parse with MacAddress validatation |
| 377 | 348 |
func TestParseWithMacAddress(t *testing.T) {
|
| 378 | 349 |
invalidMacAddress := "--mac-address=invalidMacAddress" |
| ... | ... |
@@ -61,8 +61,7 @@ func ValidateNetMode(c *Config, hc *HostConfig) error {
|
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 | 63 |
// ValidateIsolationLevel performs platform specific validation of the |
| 64 |
-// isolation level in the hostconfig structure. Linux only supports "default" |
|
| 65 |
-// which is LXC container isolation |
|
| 64 |
+// isolation level in the hostconfig structure. Linux only supports "default". |
|
| 66 | 65 |
func ValidateIsolationLevel(hc *HostConfig) error {
|
| 67 | 66 |
// We may not be passed a host config, such as in the case of docker commit |
| 68 | 67 |
if hc == nil {
|