Browse code

Merge pull request #17700 from calavera/remove_lxc

Remove LXC support.

Solomon Hykes authored on 2015/11/06 08:22:37
Showing 81 changed files
... ...
@@ -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
... ...
@@ -26,7 +26,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
26 26
 		xz-utils \
27 27
 		\
28 28
 		aufs-tools \
29
-		lxc \
30 29
 	&& rm -rf /var/lib/apt/lists/*
31 30
 
32 31
 ENV AUTO_GOPATH 1
... ...
@@ -264,7 +264,6 @@ type ContainerJSONBase struct {
264 264
 	Name            string
265 265
 	RestartCount    int
266 266
 	Driver          string
267
-	ExecDriver      string
268 267
 	MountLabel      string
269 268
 	ProcessLabel    string
270 269
 	AppArmorProfile string
... ...
@@ -40,7 +40,6 @@ RUN	apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yq \
40 40
 	libapparmor-dev \
41 41
 	libcap-dev \
42 42
 	libsqlite3-dev \
43
-	lxc=1.0* \
44 43
 	mercurial \
45 44
 	pandoc \
46 45
 	parallel \
... ...
@@ -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
... ...
@@ -25,7 +25,7 @@ The initial Docker upstart script will not work because it runs on `127.0.0.1`,
25 25
 ```
26 26
 description     "Docker daemon"
27 27
 
28
-start on filesystem and started lxc-net
28
+start on filesystem
29 29
 stop on runlevel [!2345]
30 30
 
31 31
 respawn
... ...
@@ -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"))
... ...
@@ -17,8 +17,6 @@ var (
17 17
 )
18 18
 
19 19
 // Config defines the configuration of a docker daemon.
20
-// These are the configuration settings that you pass
21
-// to the docker daemon when you launch it with say: `docker daemon -e lxc`
22 20
 type Config struct {
23 21
 	CommonConfig
24 22
 
... ...
@@ -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
159 154
deleted file mode 100644
... ...
@@ -1,9 +0,0 @@
1
-// +build freebsd
2
-
3
-package daemon
4
-
5
-// checkExecSupport returns an error if the exec driver does not support exec,
6
-// or nil if it is supported.
7
-func checkExecSupport(drivername string) error {
8
-	return nil
9
-}
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
-}
19 1
deleted file mode 100644
... ...
@@ -1,9 +0,0 @@
1
-// +build windows
2
-
3
-package daemon
4
-
5
-// checkExecSupport returns an error if the exec driver does not support exec,
6
-// or nil if it is supported.
7
-func checkExecSupport(DriverName string) error {
8
-	return nil
9
-}
... ...
@@ -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(),
135 134
deleted file mode 100644
... ...
@@ -1,9 +0,0 @@
1
-package daemon
2
-
3
-import (
4
-	"github.com/docker/docker/runconfig"
5
-)
6
-
7
-func mergeLxcConfIntoOptions(hostConfig *runconfig.HostConfig) ([]string, error) {
8
-	return nil, nil
9
-}
... ...
@@ -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
-}
... ...
@@ -4,7 +4,6 @@ package main
4 4
 
5 5
 import (
6 6
 	systemdDaemon "github.com/coreos/go-systemd/daemon"
7
-	_ "github.com/docker/docker/daemon/execdriver/lxc"
8 7
 )
9 8
 
10 9
 // notifySystem sends a message to the host when the server is ready to be used
... ...
@@ -1,7 +1,6 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	_ "github.com/docker/docker/daemon/execdriver/lxc"
5 4
 	_ "github.com/docker/docker/daemon/execdriver/native"
6 5
 	"github.com/docker/docker/pkg/reexec"
7 6
 )
... ...
@@ -212,7 +212,6 @@ recommendations.
212 212
         dpkg-sig \
213 213
         libcap-dev \
214 214
         libsqlite3-dev \
215
-        lxc=1.0* \
216 215
         mercurial \
217 216
         reprepro \
218 217
         ruby1.9.1 \
... ...
@@ -29,7 +29,6 @@ in the packages. The core dependencies are:
29 29
  - bridge-utils
30 30
  - device-mapper
31 31
  - iproute2
32
- - lxc
33 32
  - sqlite
34 33
 
35 34
 ## Installation
... ...
@@ -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
 
... ...
@@ -111,7 +111,6 @@ To get information on a container use its ID or instance name:
111 111
     "HostConfig": {
112 112
         "Binds": null,
113 113
         "ContainerIDFile": "",
114
-        "LxcConf": [],
115 114
         "Memory": 0,
116 115
         "MemorySwap": 0,
117 116
         "CpuShares": 0,
... ...
@@ -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 {