Parcourir la source

Merge pull request #3612 from EvanKrall/specify_socket_group

Create a -G option that specifies the group which unix sockets belong to...
Victor Vieux il y a 11 ans
Parent
commit
83ffc2860b

+ 34 - 12
api/server.go

@@ -1104,10 +1104,34 @@ func ServeFd(addr string, handle http.Handler) error {
 	return nil
 }
 
+func lookupGidByName(nameOrGid string) (int, error) {
+	groups, err := user.ParseGroupFilter(func(g *user.Group) bool {
+		return g.Name == nameOrGid || strconv.Itoa(g.Gid) == nameOrGid
+	})
+	if err != nil {
+		return -1, err
+	}
+	if groups != nil && len(groups) > 0 {
+		return groups[0].Gid, nil
+	}
+	return -1, fmt.Errorf("Group %s not found", nameOrGid)
+}
+
+func changeGroup(addr string, nameOrGid string) error {
+	gid, err := lookupGidByName(nameOrGid)
+	if err != nil {
+		return err
+	}
+
+	utils.Debugf("%s group found. gid: %d", nameOrGid, gid)
+	return os.Chown(addr, 0, gid)
+}
+
 // ListenAndServe sets up the required http.Server and gets it listening for
 // each addr passed in and does protocol specific checking.
-func ListenAndServe(proto, addr string, eng *engine.Engine, logging, enableCors bool, dockerVersion string) error {
+func ListenAndServe(proto, addr string, eng *engine.Engine, logging, enableCors bool, dockerVersion string, socketGroup string) error {
 	r, err := createRouter(eng, logging, enableCors, dockerVersion)
+
 	if err != nil {
 		return err
 	}
@@ -1138,16 +1162,14 @@ func ListenAndServe(proto, addr string, eng *engine.Engine, logging, enableCors
 			return err
 		}
 
-		groups, err := user.ParseGroupFilter(func(g *user.Group) bool {
-			return g.Name == "docker"
-		})
-		if err != nil {
-			return err
-		}
-		if len(groups) > 0 {
-			utils.Debugf("docker group found. gid: %d", groups[0].Gid)
-			if err := os.Chown(addr, 0, groups[0].Gid); err != nil {
-				return err
+		if socketGroup != "" {
+			if err := changeGroup(addr, socketGroup); err != nil {
+				if socketGroup == "docker" {
+					// if the user hasn't explicitly specified the group ownership, don't fail on errors.
+					utils.Debugf("Warning: could not chgrp %s to docker: %s", addr, err.Error())
+				} else {
+					return err
+				}
 			}
 		}
 	default:
@@ -1175,7 +1197,7 @@ func ServeApi(job *engine.Job) engine.Status {
 		protoAddrParts := strings.SplitN(protoAddr, "://", 2)
 		go func() {
 			log.Printf("Listening for HTTP on %s (%s)\n", protoAddrParts[0], protoAddrParts[1])
-			chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version"))
+			chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version"), job.Getenv("SocketGroup"))
 		}()
 	}
 

+ 2 - 0
docker/docker.go

@@ -32,6 +32,7 @@ func main() {
 		bridgeIp             = flag.String([]string{"#bip", "-bip"}, "", "Use this CIDR notation address for the network bridge's IP, not compatible with -b")
 		pidfile              = flag.String([]string{"p", "-pidfile"}, "/var/run/docker.pid", "Path to use for daemon PID file")
 		flRoot               = flag.String([]string{"g", "-graph"}, "/var/lib/docker", "Path to use as the root of the docker runtime")
+		flSocketGroup        = flag.String([]string{"G", "-group"}, "docker", "Group to assign the unix socket specified by -H when running in daemon mode; use '' (the empty string) to disable setting of a group")
 		flEnableCors         = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API")
 		flDns                = opts.NewListOpts(opts.ValidateIp4Address)
 		flEnableIptables     = flag.Bool([]string{"#iptables", "-iptables"}, true, "Disable docker's addition of iptables rules")
@@ -138,6 +139,7 @@ func main() {
 		job.SetenvBool("Logging", true)
 		job.SetenvBool("EnableCors", *flEnableCors)
 		job.Setenv("Version", dockerversion.VERSION)
+		job.Setenv("SocketGroup", *flSocketGroup)
 		if err := job.Run(); err != nil {
 			log.Fatal(err)
 		}

+ 5 - 2
docs/sources/installation/ubuntulinux.rst

@@ -182,9 +182,12 @@ daemon will make the ownership of the Unix socket read/writable by the
 *docker* group when the daemon starts. The ``docker`` daemon must
 always run as the root user, but if you run the ``docker`` client as a user in
 the *docker* group then you don't need to add ``sudo`` to all the
-client commands.  
+client commands. As of 0.9.0, you can specify that a group other than ``docker``
+should own the Unix socket with the ``-G`` option.
+
+.. warning:: The *docker* group (or the group specified with ``-G``) is
+   root-equivalent.
 
-.. warning:: The *docker* group is root-equivalent.
 
 **Example:**
 

+ 1 - 0
docs/sources/reference/commandline/cli.rst

@@ -71,6 +71,7 @@ Commands
     Usage of docker:
       -D, --debug=false: Enable debug mode
       -H, --host=[]: Multiple tcp://host:port or unix://path/to/socket to bind in daemon mode, single connection otherwise. systemd socket activation can be used with fd://[socketfd].
+      -G, --group="docker": Group to assign the unix socket specified by -H when running in daemon mode; use '' (the empty string) to disable setting of a group
       --api-enable-cors=false: Enable CORS headers in the remote API
       -b, --bridge="": Attach containers to a pre-existing network bridge; use 'none' to disable container networking
       --bip="": Use this CIDR notation address for the network bridge's IP, not compatible with -b