This changes the way the exec drivers work by not specifing a -driver flag on reexec. For each of the exec drivers they register their own functions that will be matched aginst the argv 0 on exec and called if they match. This also allows any functionality to be added to docker so that the binary can be reexec'd and any type of function can be called. I moved the flag parsing on docker exec to the specific initializers so that the implementations do not bleed into one another. This also allows for more flexability within reexec initializers to specify their own flags and options. Signed-off-by: Michael Crosby <michael@docker.com> Upstream-commit: 73210671764fc3de133a627205582e069e1ff43d Component: engine
116 lines
2.5 KiB
Go
116 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/docker/docker/api"
|
|
"github.com/docker/docker/api/client"
|
|
"github.com/docker/docker/dockerversion"
|
|
flag "github.com/docker/docker/pkg/mflag"
|
|
"github.com/docker/docker/reexec"
|
|
"github.com/docker/docker/utils"
|
|
)
|
|
|
|
const (
|
|
defaultCaFile = "ca.pem"
|
|
defaultKeyFile = "key.pem"
|
|
defaultCertFile = "cert.pem"
|
|
)
|
|
|
|
func main() {
|
|
if reexec.Init() {
|
|
return
|
|
}
|
|
|
|
flag.Parse()
|
|
|
|
if *flVersion {
|
|
showVersion()
|
|
return
|
|
}
|
|
if *flDebug {
|
|
os.Setenv("DEBUG", "1")
|
|
}
|
|
|
|
if flHosts.Len() == 0 {
|
|
defaultHost := os.Getenv("DOCKER_HOST")
|
|
if defaultHost == "" || *flDaemon {
|
|
// If we do not have a host, default to unix socket
|
|
defaultHost = fmt.Sprintf("unix://%s", api.DEFAULTUNIXSOCKET)
|
|
}
|
|
if _, err := api.ValidateHost(defaultHost); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
flHosts.Set(defaultHost)
|
|
}
|
|
|
|
if *flDaemon {
|
|
mainDaemon()
|
|
return
|
|
}
|
|
|
|
if flHosts.Len() > 1 {
|
|
log.Fatal("Please specify only one -H")
|
|
}
|
|
protoAddrParts := strings.SplitN(flHosts.GetAll()[0], "://", 2)
|
|
|
|
var (
|
|
cli *client.DockerCli
|
|
tlsConfig tls.Config
|
|
)
|
|
tlsConfig.InsecureSkipVerify = true
|
|
|
|
// If we should verify the server, we need to load a trusted ca
|
|
if *flTlsVerify {
|
|
*flTls = true
|
|
certPool := x509.NewCertPool()
|
|
file, err := ioutil.ReadFile(*flCa)
|
|
if err != nil {
|
|
log.Fatalf("Couldn't read ca cert %s: %s", *flCa, err)
|
|
}
|
|
certPool.AppendCertsFromPEM(file)
|
|
tlsConfig.RootCAs = certPool
|
|
tlsConfig.InsecureSkipVerify = false
|
|
}
|
|
|
|
// If tls is enabled, try to load and send client certificates
|
|
if *flTls || *flTlsVerify {
|
|
_, errCert := os.Stat(*flCert)
|
|
_, errKey := os.Stat(*flKey)
|
|
if errCert == nil && errKey == nil {
|
|
*flTls = true
|
|
cert, err := tls.LoadX509KeyPair(*flCert, *flKey)
|
|
if err != nil {
|
|
log.Fatalf("Couldn't load X509 key pair: %s. Key encrypted?", err)
|
|
}
|
|
tlsConfig.Certificates = []tls.Certificate{cert}
|
|
}
|
|
}
|
|
|
|
if *flTls || *flTlsVerify {
|
|
cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], &tlsConfig)
|
|
} else {
|
|
cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], nil)
|
|
}
|
|
|
|
if err := cli.ParseCommands(flag.Args()...); err != nil {
|
|
if sterr, ok := err.(*utils.StatusError); ok {
|
|
if sterr.Status != "" {
|
|
log.Println(sterr.Status)
|
|
}
|
|
os.Exit(sterr.StatusCode)
|
|
}
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func showVersion() {
|
|
fmt.Printf("Docker version %s, build %s\n", dockerversion.VERSION, dockerversion.GITCOMMIT)
|
|
}
|