Merge pull request #3612 from EvanKrall/specify_socket_group

Create a -G option that specifies the group which unix sockets belong to...
This commit is contained in:
Victor Vieux 2014-03-06 11:30:17 -08:00
commit 83ffc2860b
4 changed files with 42 additions and 14 deletions

View File

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

View File

@ -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") 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") 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") 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") flEnableCors = flag.Bool([]string{"#api-enable-cors", "-api-enable-cors"}, false, "Enable CORS headers in the remote API")
flDns = opts.NewListOpts(opts.ValidateIp4Address) flDns = opts.NewListOpts(opts.ValidateIp4Address)
flEnableIptables = flag.Bool([]string{"#iptables", "-iptables"}, true, "Disable docker's addition of iptables rules") 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("Logging", true)
job.SetenvBool("EnableCors", *flEnableCors) job.SetenvBool("EnableCors", *flEnableCors)
job.Setenv("Version", dockerversion.VERSION) job.Setenv("Version", dockerversion.VERSION)
job.Setenv("SocketGroup", *flSocketGroup)
if err := job.Run(); err != nil { if err := job.Run(); err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -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 *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 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 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:** **Example:**

View File

@ -71,6 +71,7 @@ Commands
Usage of docker: Usage of docker:
-D, --debug=false: Enable debug mode -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]. -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 --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 -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 --bip="": Use this CIDR notation address for the network bridge's IP, not compatible with -b