Jelajahi Sumber

Merge branch 'master' into refactor_cgo_in_go

Guillaume J. Charmes 11 tahun lalu
induk
melakukan
a58fef9f13
11 mengubah file dengan 591 tambahan dan 17 penghapusan
  1. 3 0
      .gitignore
  2. 7 0
      CONTRIBUTING.md
  3. 1 1
      archive/changes.go
  4. 4 2
      archive/diff.go
  5. 11 0
      archive/stat_darwin.go
  6. 11 0
      archive/stat_linux.go
  7. 77 0
      contrib/mkseccomp.pl
  8. 444 0
      contrib/mkseccomp.sample
  9. 20 11
      hack/RELEASE-CHECKLIST.md
  10. 2 1
      runtime.go
  11. 11 2
      server.go

+ 3 - 0
.gitignore

@@ -1,3 +1,6 @@
+# Docker project generated files to ignore
+#  if you want to ignore files created by your editor/tools,
+#  please consider a global .gitignore https://help.github.com/articles/ignoring-files
 .vagrant*
 .vagrant*
 bin
 bin
 docker/docker
 docker/docker

+ 7 - 0
CONTRIBUTING.md

@@ -4,6 +4,13 @@ Want to hack on Docker? Awesome! Here are instructions to get you
 started. They are probably not perfect, please let us know if anything
 started. They are probably not perfect, please let us know if anything
 feels wrong or incomplete.
 feels wrong or incomplete.
 
 
+## Reporting Issues
+
+When reporting [issues](https://github.com/dotcloud/docker/issues) 
+on Github please include your host OS ( Ubuntu 12.04, Fedora 19, etc... )
+and the output of `docker version` along with the output of `docker info` if possible.  
+This information will help us review and fix your issue faster.
+
 ## Build Environment
 ## Build Environment
 
 
 For instructions on setting up your development environment, please
 For instructions on setting up your development environment, please

+ 1 - 1
archive/changes.go

@@ -181,7 +181,7 @@ func (info *FileInfo) addChanges(oldInfo *FileInfo, changes *[]Change) {
 				oldStat.Rdev != newStat.Rdev ||
 				oldStat.Rdev != newStat.Rdev ||
 				// Don't look at size for dirs, its not a good measure of change
 				// Don't look at size for dirs, its not a good measure of change
 				(oldStat.Size != newStat.Size && oldStat.Mode&syscall.S_IFDIR != syscall.S_IFDIR) ||
 				(oldStat.Size != newStat.Size && oldStat.Mode&syscall.S_IFDIR != syscall.S_IFDIR) ||
-				oldStat.Mtim != newStat.Mtim {
+				getLastModification(oldStat) != getLastModification(newStat) {
 				change := Change{
 				change := Change{
 					Path: newChild.path(),
 					Path: newChild.path(),
 					Kind: ChangeModify,
 					Kind: ChangeModify,

+ 4 - 2
archive/diff.go

@@ -83,8 +83,10 @@ func ApplyLayer(dest string, layer Archive) error {
 	}
 	}
 
 
 	for k, v := range modifiedDirs {
 	for k, v := range modifiedDirs {
-		aTime := time.Unix(v.Atim.Unix())
-		mTime := time.Unix(v.Mtim.Unix())
+		lastAccess := getLastAccess(v)
+		lastModification := getLastModification(v)
+		aTime := time.Unix(lastAccess.Unix())
+		mTime := time.Unix(lastModification.Unix())
 
 
 		if err := os.Chtimes(k, aTime, mTime); err != nil {
 		if err := os.Chtimes(k, aTime, mTime); err != nil {
 			return err
 			return err

+ 11 - 0
archive/stat_darwin.go

@@ -0,0 +1,11 @@
+package archive
+
+import "syscall"
+
+func getLastAccess(stat *syscall.Stat_t) syscall.Timespec {
+	return stat.Atimespec
+}
+
+func getLastModification(stat *syscall.Stat_t) syscall.Timespec {
+	return stat.Mtimespec
+}

+ 11 - 0
archive/stat_linux.go

@@ -0,0 +1,11 @@
+package archive
+
+import "syscall"
+
+func getLastAccess(stat *syscall.Stat_t) syscall.Timespec {
+	return stat.Atim
+}
+
+func getLastModification(stat *syscall.Stat_t) syscall.Timespec {
+	return stat.Mtim
+}

+ 77 - 0
contrib/mkseccomp.pl

@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+#
+# A simple helper script to help people build seccomp profiles for
+# Docker/LXC.  The goal is mostly to reduce the attack surface to the
+# kernel, by restricting access to rarely used, recently added or not used
+# syscalls.
+#
+# This script processes one or more files which contain the list of system
+# calls to be allowed.  See mkseccomp.sample for more information how you
+# can configure the list of syscalls.  When run, this script produces output
+# which, when stored in a file, can be passed to docker as follows:
+#
+# docker run -lxc-conf="lxc.seccomp=$file" <rest of arguments>
+#
+# The included sample file shows how to cut about a quarter of all syscalls,
+# which affecting most applications.
+#
+# For specific situations it is possible to reduce the list further. By
+# reducing the list to just those syscalls required by a certain application
+# you can make it difficult for unknown/unexpected code to run.
+#
+# Run this script as follows:
+#
+# ./mkseccomp.pl < mkseccomp.sample >syscalls.list
+# or
+# ./mkseccomp.pl mkseccomp.sample >syscalls.list
+#
+# Multiple files can be specified, in which case the lists of syscalls are
+# combined.
+#
+# By Martijn van Oosterhout <kleptog@svana.org> Nov 2013
+
+# How it works:
+#
+# This program basically spawns two processes to form a chain like:
+#
+# <process data section to prefix __NR_> | cpp | <add header and filter unknown syscalls>
+
+use strict;
+use warnings;
+
+if( -t ) {
+    print STDERR "Helper script to make seccomp filters for Docker/LXC.\n";
+    print STDERR "Usage: mkseccomp.pl [files...]\n";
+    exit 1;
+}
+
+my $pid = open(my $in, "-|") // die "Couldn't fork1 ($!)\n";
+
+if($pid == 0) {  # Child
+    $pid = open(my $out, "|-") // die "Couldn't fork2 ($!)\n";
+
+    if($pid == 0) { # Child, which execs cpp
+        exec "cpp" or die "Couldn't exec cpp ($!)\n";
+        exit 1;
+    }
+
+    # Process the DATA section and output to cpp
+    print $out "#include <sys/syscall.h>\n";
+    while(<>) {
+        if(/^\w/) {
+            print $out "__NR_$_";
+        }
+    }
+    close $out;
+    exit 0;
+
+}
+
+# Print header and then process output from cpp.
+print "1\n";
+print "whitelist\n";
+
+while(<$in>) {
+    print if( /^[0-9]/ );
+}
+

+ 444 - 0
contrib/mkseccomp.sample

@@ -0,0 +1,444 @@
+/* This sample file is an example for mkseccomp.pl to produce a seccomp file
+ * which restricts syscalls that are only useful for an admin but allows the
+ * vast majority of normal userspace programs to run normally.
+ *
+ * The format of this file is one line per syscall.  This is then processed
+ * and passed to 'cpp' to convert the names to numbers using whatever is
+ * correct for your platform.  As such C-style comments are permitted.  Note
+ * this also means that C preprocessor macros are also allowed.  So it is
+ * possible to create groups surrounded by #ifdef/#endif and control their
+ * inclusion via #define (not #include).
+ *
+ * Syscalls that don't exist on your architecture are silently filtered out.
+ * Syscalls marked with (*) are required for a container to spawn a bash
+ * shell successfully (not necessarily full featured).  Listing the same
+ * syscall multiple times is no problem.
+ *
+ * If you want to make a list specifically for one application the easiest
+ * way is to run the application under strace, like so:
+ *
+ * $ strace -f -q -c -o strace.out application args...
+ *
+ * Once you have a reasonable sample of the execution of the program, exit
+ * it.  The file strace.out will have a summary of the syscalls used.  Copy
+ * that list into this file, comment out everything else except the starred
+ * syscalls (which you need for the container to start) and you're done.
+ *
+ * To get the list of syscalls from the strace output this works well for
+ * me
+ *
+ * $ cut -c52 < strace.out
+ *
+ * This sample list was compiled as a combination of all the syscalls
+ * available on i386 and amd64 on Ubuntu Precise, as such it may not contain
+ * everything and not everything may be relevent for your system.  This
+ * shouldn't be a problem.
+ */
+
+// Filesystem/File descriptor related
+access                 // (*)
+chdir                  // (*)
+chmod
+chown
+chown32
+close                  // (*)
+creat
+dup                    // (*)
+dup2                   // (*)
+dup3
+epoll_create
+epoll_create1
+epoll_ctl
+epoll_ctl_old
+epoll_pwait
+epoll_wait
+epoll_wait_old
+eventfd
+eventfd2
+faccessat              // (*)
+fadvise64
+fadvise64_64
+fallocate
+fanotify_init
+fanotify_mark
+ioctl                  // (*)
+fchdir
+fchmod
+fchmodat
+fchown
+fchown32
+fchownat
+fcntl                  // (*)
+fcntl64
+fdatasync
+fgetxattr
+flistxattr
+flock
+fremovexattr
+fsetxattr
+fstat                  // (*)
+fstat64
+fstatat64
+fstatfs
+fstatfs64
+fsync
+ftruncate
+ftruncate64
+getcwd                 // (*)
+getdents               // (*)
+getdents64
+getxattr
+inotify_add_watch
+inotify_init
+inotify_init1
+inotify_rm_watch
+io_cancel
+io_destroy
+io_getevents
+io_setup
+io_submit
+lchown
+lchown32
+lgetxattr
+link
+linkat
+listxattr
+llistxattr
+llseek
+_llseek
+lremovexattr
+lseek                  // (*)
+lsetxattr
+lstat
+lstat64
+mkdir
+mkdirat
+mknod
+mknodat
+newfstatat
+_newselect
+oldfstat
+oldlstat
+oldolduname
+oldstat
+olduname
+oldwait4
+open                   // (*)
+openat                 // (*)
+pipe                   // (*)
+pipe2
+poll
+ppoll
+pread64
+preadv
+futimesat
+pselect6
+pwrite64
+pwritev
+read                   // (*)
+readahead
+readdir
+readlink
+readlinkat
+readv
+removexattr
+rename
+renameat
+rmdir
+select
+sendfile
+sendfile64
+setxattr
+splice
+stat                   // (*)
+stat64
+statfs                 // (*)
+statfs64
+symlink
+symlinkat
+sync
+sync_file_range
+sync_file_range2
+syncfs
+tee
+truncate
+truncate64
+umask
+unlink
+unlinkat
+ustat
+utime
+utimensat
+utimes
+write                  // (*)
+writev
+
+// Network related
+accept
+accept4
+bind                   // (*)
+connect                // (*)
+getpeername
+getsockname            // (*)
+getsockopt
+listen
+recv
+recvfrom               // (*)
+recvmmsg
+recvmsg
+send
+sendmmsg
+sendmsg
+sendto                 // (*)
+setsockopt
+shutdown
+socket                 // (*)
+socketcall
+socketpair
+
+// Signal related
+pause
+rt_sigaction           // (*)
+rt_sigpending
+rt_sigprocmask         // (*)
+rt_sigqueueinfo
+rt_sigreturn           // (*)
+rt_sigsuspend
+rt_sigtimedwait
+rt_tgsigqueueinfo
+sigaction
+sigaltstack            // (*)
+signal
+signalfd
+signalfd4
+sigpending
+sigprocmask
+sigreturn
+sigsuspend
+
+// Other needed POSIX
+alarm
+brk                    // (*)
+clock_adjtime
+clock_getres
+clock_gettime
+clock_nanosleep
+//clock_settime
+gettimeofday
+nanosleep
+nice
+sysinfo
+syslog
+time
+timer_create
+timer_delete
+timerfd_create
+timerfd_gettime
+timerfd_settime
+timer_getoverrun
+timer_gettime
+timer_settime
+times
+uname                  // (*)
+
+// Memory control
+madvise
+mbind
+mincore
+mlock
+mlockall
+mmap                   // (*)
+mmap2
+mprotect               // (*)
+mremap
+msync
+munlock
+munlockall
+munmap                 // (*)
+remap_file_pages
+set_mempolicy
+vmsplice
+
+// Process control
+capget
+//capset
+clone                  // (*)
+execve                 // (*)
+exit                   // (*)
+exit_group             // (*)
+fork
+getcpu
+getpgid
+getpgrp                // (*)
+getpid                 // (*)
+getppid                // (*)
+getpriority
+getresgid
+getresgid32
+getresuid
+getresuid32
+getrlimit              // (*)
+getrusage
+getsid
+getuid                 // (*)
+getuid32
+getegid                // (*)
+getegid32
+geteuid                // (*)
+geteuid32
+getgid                 // (*)
+getgid32
+getgroups
+getgroups32
+getitimer
+get_mempolicy
+kill
+//personality
+prctl
+prlimit64
+sched_getaffinity
+sched_getparam
+sched_get_priority_max
+sched_get_priority_min
+sched_getscheduler
+sched_rr_get_interval
+//sched_setaffinity
+//sched_setparam
+//sched_setscheduler
+sched_yield
+setfsgid
+setfsgid32
+setfsuid
+setfsuid32
+setgid
+setgid32
+setgroups
+setgroups32
+setitimer
+setpgid                // (*)
+setpriority
+setregid
+setregid32
+setresgid
+setresgid32
+setresuid
+setresuid32
+setreuid
+setreuid32
+setrlimit
+setsid
+setuid
+setuid32
+ugetrlimit
+vfork
+wait4                  // (*)
+waitid
+waitpid
+
+// IPC
+ipc
+mq_getsetattr
+mq_notify
+mq_open
+mq_timedreceive
+mq_timedsend
+mq_unlink
+msgctl
+msgget
+msgrcv
+msgsnd
+semctl
+semget
+semop
+semtimedop
+shmat
+shmctl
+shmdt
+shmget
+
+// Linux specific, mostly needed for thread-related stuff
+arch_prctl             // (*)
+get_robust_list
+get_thread_area
+gettid
+futex                  // (*)
+restart_syscall        // (*)
+set_robust_list        // (*)
+set_thread_area
+set_tid_address        // (*)
+tgkill
+tkill
+
+// Admin syscalls, these are blocked
+//acct
+//adjtimex
+//bdflush
+//chroot
+//create_module
+//delete_module
+//get_kernel_syms      // Obsolete
+//idle                 // Obsolete
+//init_module
+//ioperm
+//iopl
+//ioprio_get
+//ioprio_set
+//kexec_load
+//lookup_dcookie       // oprofile only?
+//migrate_pages        // NUMA
+//modify_ldt
+//mount
+//move_pages           // NUMA
+//name_to_handle_at    // NFS server
+//nfsservctl           // NFS server
+//open_by_handle_at    // NFS server
+//perf_event_open
+//pivot_root
+//process_vm_readv     // For debugger
+//process_vm_writev    // For debugger
+//ptrace               // For debugger
+//query_module
+//quotactl
+//reboot
+//setdomainname
+//sethostname
+//setns
+//settimeofday
+//sgetmask             // Obsolete
+//ssetmask             // Obsolete
+//stime
+//swapoff
+//swapon
+//_sysctl
+//sysfs
+//sys_setaltroot
+//umount
+//umount2
+//unshare
+//uselib
+//vhangup
+//vm86
+//vm86old
+
+// Kernel key management
+//add_key
+//keyctl
+//request_key
+
+// Unimplemented
+//afs_syscall
+//break
+//ftime
+//getpmsg
+//gtty
+//lock
+//madvise1
+//mpx
+//prof
+//profil
+//putpmsg
+//security
+//stty
+//tuxcall
+//ulimit
+//vserver

+ 20 - 11
hack/RELEASE-CHECKLIST.md

@@ -5,7 +5,6 @@ So you're in charge of a Docker release? Cool. Here's what to do.
 If your experience deviates from this document, please document the changes
 If your experience deviates from this document, please document the changes
 to keep it up-to-date.
 to keep it up-to-date.
 
 
-
 ### 1. Pull from master and create a release branch
 ### 1. Pull from master and create a release branch
 
 
 ```bash
 ```bash
@@ -13,6 +12,7 @@ export VERSION=vXXX
 git checkout release
 git checkout release
 git pull
 git pull
 git checkout -b bump_$VERSION
 git checkout -b bump_$VERSION
+git merge origin/master
 ```
 ```
 
 
 ### 2. Update CHANGELOG.md
 ### 2. Update CHANGELOG.md
@@ -54,10 +54,14 @@ EXAMPLES:
 
 
 ### 3. Change the contents of the VERSION file
 ### 3. Change the contents of the VERSION file
 
 
+```bash
+echo ${VERSION#v} > VERSION
+```
+
 ### 4. Run all tests
 ### 4. Run all tests
 
 
 ```bash
 ```bash
-docker run -privileged -lxc-conf=lxc.aa_profile=unconfined docker hack/make.sh test
+docker run -privileged docker hack/make.sh test
 ```
 ```
 
 
 ### 5. Test the docs
 ### 5. Test the docs
@@ -79,8 +83,8 @@ git push origin bump_$VERSION
 ### 8. Apply tag
 ### 8. Apply tag
 
 
 ```bash
 ```bash
-git tag -a v$VERSION # Don't forget the v!
-git push --tags
+git tag -a $VERSION -m $VERSION bump_$VERSION
+git push origin $VERSION
 ```
 ```
 
 
 Merging the pull request to the release branch will automatically
 Merging the pull request to the release branch will automatically
@@ -91,6 +95,9 @@ documentation releases, see ``docs/README.md``
 
 
 ### 9. Go to github to merge the bump_$VERSION into release
 ### 9. Go to github to merge the bump_$VERSION into release
 
 
+Don't forget to push that pretty blue button to delete the leftover
+branch afterwards!
+
 ### 10. Publish binaries
 ### 10. Publish binaries
 
 
 To run this you will need access to the release credentials.
 To run this you will need access to the release credentials.
@@ -107,17 +114,19 @@ docker run  \
        -e AWS_ACCESS_KEY=$(cat ~/.aws/access_key) \
        -e AWS_ACCESS_KEY=$(cat ~/.aws/access_key) \
        -e AWS_SECRET_KEY=$(cat ~/.aws/secret_key) \
        -e AWS_SECRET_KEY=$(cat ~/.aws/secret_key) \
        -e GPG_PASSPHRASE=supersecretsesame \
        -e GPG_PASSPHRASE=supersecretsesame \
-       -privileged -lxc-conf=lxc.aa_profile=unconfined \
-       -t -i \
+       -i -t -privileged \
        docker \
        docker \
        hack/release.sh
        hack/release.sh
 ```
 ```
 
 
-It will build and upload the binaries on the specified bucket (you should
-use test.docker.io for general testing, and once everything is fine,
-switch to get.docker.io).
-
+It will run the test suite one more time, build the binaries and packages,
+and upload to the specified bucket (you should use test.docker.io for
+general testing, and once everything is fine, switch to get.docker.io).
 
 
-### 11. Rejoice!
+### 11. Rejoice and Evangelize!
 
 
 Congratulations! You're done.
 Congratulations! You're done.
+
+Go forth and announce the glad tidings of the new release in `#docker`,
+`#docker-dev`, on the [mailing list](https://groups.google.com/forum/#!forum/docker-dev),
+and on Twitter!

+ 2 - 1
runtime.go

@@ -422,7 +422,8 @@ func (runtime *Runtime) Create(config *Config, name string) (*Container, []strin
 	if _, err := runtime.containerGraph.Set(name, id); err != nil {
 	if _, err := runtime.containerGraph.Set(name, id); err != nil {
 		if strings.HasSuffix(err.Error(), "name are not unique") {
 		if strings.HasSuffix(err.Error(), "name are not unique") {
 			conflictingContainer, _ := runtime.GetByName(name)
 			conflictingContainer, _ := runtime.GetByName(name)
-			return nil, nil, fmt.Errorf("Conflict, The name %s is already assigned to %s. You have to delete (or rename) that container to be able to assign %s to a container again.", name, utils.TruncateID(conflictingContainer.ID), name)
+			nameAsKnownByUser := strings.TrimPrefix(name, "/")
+			return nil, nil, fmt.Errorf("Conflict, The name %s is already assigned to %s. You have to delete (or rename) that container to be able to assign %s to a container again.", nameAsKnownByUser, utils.TruncateID(conflictingContainer.ID), nameAsKnownByUser)
 		}
 		}
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}

+ 11 - 2
server.go

@@ -985,7 +985,17 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	if _, err := srv.poolAdd("pull", localName+":"+tag); err != nil {
+
+	out = utils.NewWriteFlusher(out)
+
+	c, err := srv.poolAdd("pull", localName+":"+tag)
+	if err != nil {
+		if c != nil {
+			// Another pull of the same repository is already taking place; just wait for it to finish
+			out.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName))
+			<-c
+			return nil
+		}
 		return err
 		return err
 	}
 	}
 	defer srv.poolRemove("pull", localName+":"+tag)
 	defer srv.poolRemove("pull", localName+":"+tag)
@@ -1001,7 +1011,6 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut
 		localName = remoteName
 		localName = remoteName
 	}
 	}
 
 
-	out = utils.NewWriteFlusher(out)
 	err = srv.pullRepository(r, out, localName, remoteName, tag, endpoint, sf, parallel)
 	err = srv.pullRepository(r, out, localName, remoteName, tag, endpoint, sf, parallel)
 	if err == registry.ErrLoginRequired {
 	if err == registry.ErrLoginRequired {
 		return err
 		return err