Browse code

Remove LXC support.

The LXC driver was deprecated in Docker 1.8.
Following the deprecation rules, we can remove a deprecated feature
after two major releases. LXC won't be supported anymore starting on Docker 1.10.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2015/11/05 04:39:12
Showing 62 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
... ...
@@ -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")
... ...
@@ -1379,7 +1379,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
... ...
@@ -135,7 +135,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 +323,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,7 @@ __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)" \
544
+                "($help -e --exec-driver)"{-e=,--exec-driver=}"[Exec driver to use]:driver:(native windows)" \
545 545
                 "($help)*--exec-opt=[Set exec driver options]:exec driver options: " \
546 546
                 "($help)--exec-root=[Root of the Docker execdriver]:path:_directories" \
547 547
                 "($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
... ...
@@ -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
 
... ...
@@ -261,7 +261,6 @@ func (container *Container) jsonPath() (string, error) {
261 261
 	return container.getRootResourcePath("config.json")
262 262
 }
263 263
 
264
-// This method must be exported to be used from the lxc template
265 264
 // This directory is only usable when the container is running
266 265
 func (container *Container) rootfsPath() string {
267 266
 	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
 	}
... ...
@@ -786,13 +785,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,
... ...
@@ -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"`
... ...
@@ -6,24 +6,15 @@ import (
6 6
 	"fmt"
7 7
 	"path"
8 8
 
9
-	"github.com/Sirupsen/logrus"
10 9
 	"github.com/docker/docker/daemon/execdriver"
11
-	"github.com/docker/docker/daemon/execdriver/lxc"
12 10
 	"github.com/docker/docker/daemon/execdriver/native"
13 11
 	"github.com/docker/docker/pkg/sysinfo"
14 12
 )
15 13
 
16 14
 // NewDriver returns a new execdriver.Driver from the given name configured with the provided options.
17 15
 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)
16
+	if name != "native" {
17
+		return nil, fmt.Errorf("unknown exec driver %s", name)
27 18
 	}
28
-	return nil, fmt.Errorf("unknown exec driver %s", name)
19
+	return native.NewDriver(path.Join(root, "execdriver", "native"), initPath, options)
29 20
 }
30 21
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
 
1511 1511
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
 
... ...
@@ -174,7 +174,6 @@ Create a container
174 174
            "HostConfig": {
175 175
              "Binds": ["/tmp:/tmp"],
176 176
              "Links": ["redis3:redis"],
177
-             "LxcConf": {"lxc.utsname":"docker"},
178 177
              "Memory": 0,
179 178
              "MemorySwap": 0,
180 179
              "MemoryReservation": 0,
... ...
@@ -270,8 +269,6 @@ Json Parameters:
270 270
            + `volume_name:container_path:ro` to make the bind mount read-only inside the container.
271 271
     -   **Links** - A list of links for the container. Each link entry should be
272 272
           in the form of `container_name:alias`.
273
-    -   **LxcConf** - LXC specific configurations. These configurations only
274
-          work when using the `lxc` execution driver.
275 273
     -   **PortBindings** - A map of exposed container ports and the host port they
276 274
           should map to. A JSON object in the form
277 275
           `{ <port>/<protocol>: [{ "HostPort": "<port>" }] }`
... ...
@@ -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
... ...
@@ -439,11 +439,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
 
... ...
@@ -933,21 +932,18 @@ one can use this flag:
933 933
     $ docker run -ti --rm --group-add audio  --group-add dbus --group-add 777 busybox id
934 934
     uid=0(root) gid=0(root) groups=10(wheel),29(audio),81(dbus),777
935 935
 
936
-## Runtime privilege, Linux capabilities, and LXC configuration
936
+## Runtime privilege and Linux capabilities
937 937
 
938 938
     --cap-add: Add Linux capabilities
939 939
     --cap-drop: Drop Linux capabilities
940 940
     --privileged=false: Give extended privileges to this container
941 941
     --device=[]: Allows you to run devices inside the container without the --privileged flag.
942
-    --lxc-conf=[]: Add custom lxc options
943 942
 
944 943
 By default, Docker containers are "unprivileged" and cannot, for
945 944
 example, run a Docker daemon inside a Docker container. This is because
946 945
 by default a container is not allowed to access any devices, but a
947
-"privileged" container is given access to all devices (see [lxc-template.go](
948
-https://github.com/docker/docker/blob/master/daemon/execdriver/lxc/lxc_template.go)
949
-and documentation on [cgroups devices](
950
-https://www.kernel.org/doc/Documentation/cgroups/devices.txt)).
946
+"privileged" container is given access to all devices (see 
947
+the documentation on [cgroups devices](https://www.kernel.org/doc/Documentation/cgroups/devices.txt)).
951 948
 
952 949
 When the operator executes `docker run --privileged`, Docker will enable
953 950
 to access to all devices on the host as well as set some configuration
... ...
@@ -1061,22 +1057,6 @@ To mount a FUSE based filesystem, you need to combine both `--cap-add` and
1061 1061
     ....
1062 1062
 
1063 1063
 
1064
-If the Docker daemon was started using the `lxc` exec-driver
1065
-(`docker daemon --exec-driver=lxc`) then the operator can also specify LXC options
1066
-using one or more `--lxc-conf` parameters. These can be new parameters or
1067
-override existing parameters from the [lxc-template.go](
1068
-https://github.com/docker/docker/blob/master/daemon/execdriver/lxc/lxc_template.go).
1069
-Note that in the future, a given host's docker daemon may not use LXC, so this
1070
-is an implementation-specific configuration meant for operators already
1071
-familiar with using LXC directly.
1072
-
1073
-> **Note:**
1074
-> If you use `--lxc-conf` to modify a container's configuration which is also
1075
-> managed by the Docker daemon, then the Docker daemon will not know about this
1076
-> modification, and you will need to manage any conflicts yourself. For example,
1077
-> you can use `--lxc-conf` to set a container's IP address, but this will not be
1078
-> reflected in the `/etc/hosts` file.
1079
-
1080 1064
 ## Logging drivers (--log-driver)
1081 1065
 
1082 1066
 The container can have a different logging driver than the Docker daemon. Use
... ...
@@ -1258,7 +1238,6 @@ above, or already defined by the developer with a Dockerfile `ENV`:
1258 1258
     declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
1259 1259
     declare -x PWD="/"
1260 1260
     declare -x SHLVL="1"
1261
-    declare -x container="lxc"
1262 1261
     declare -x deep="purple"
1263 1262
 
1264 1263
 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 \
... ...
@@ -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,
... ...
@@ -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)
... ...
@@ -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{
... ...
@@ -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
 )
... ...
@@ -437,22 +436,3 @@ func (s *DockerSuite) TestRunInvalidCPUShares(c *check.C) {
437 437
 	expected = "The maximum allowed cpu-shares is"
438 438
 	c.Assert(out, checker.Contains, expected)
439 439
 }
440
-
441
-func (s *DockerSuite) TestRunWithCorrectMemorySwapOnLXC(c *check.C) {
442
-	testRequires(c, memoryLimitSupport)
443
-	testRequires(c, swapMemorySupport)
444
-	testRequires(c, SameHostDaemon)
445
-
446
-	out, _ := dockerCmd(c, "run", "-d", "-m", "32m", "--memory-swap", "64m", "busybox", "top")
447
-	if _, err := os.Stat("/sys/fs/cgroup/memory/lxc"); err != nil {
448
-		c.Skip("Excecution driver must be LXC for this test")
449
-	}
450
-	id := strings.TrimSpace(out)
451
-	memorySwap, err := ioutil.ReadFile(fmt.Sprintf("/sys/fs/cgroup/memory/lxc/%s/memory.memsw.limit_in_bytes", id))
452
-	c.Assert(err, check.IsNil)
453
-	cgSwap, err := strconv.ParseInt(strings.TrimSpace(string(memorySwap)), 10, 64)
454
-	c.Assert(err, check.IsNil)
455
-	swap, err := units.RAMInBytes("64m")
456
-	c.Assert(err, check.IsNil)
457
-	c.Assert(cgSwap, check.Equals, swap)
458
-}
... ...
@@ -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
 
... ...
@@ -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
... ...
@@ -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 {