зеркало из https://github.com/microsoft/docker.git
Remove deprecated server/ package
Victory! Signed-off-by: Solomon Hykes <solomon@docker.com>
This commit is contained in:
Родитель
491deae9b8
Коммит
63503cafe4
|
@ -1194,7 +1194,7 @@ func ServeFd(addr string, handle http.Handler) error {
|
||||||
chErrors := make(chan error, len(ls))
|
chErrors := make(chan error, len(ls))
|
||||||
|
|
||||||
// We don't want to start serving on these sockets until the
|
// We don't want to start serving on these sockets until the
|
||||||
// "initserver" job has completed. Otherwise required handlers
|
// daemon is initialized and installed. Otherwise required handlers
|
||||||
// won't be ready.
|
// won't be ready.
|
||||||
<-activationLock
|
<-activationLock
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/docker/docker/events"
|
"github.com/docker/docker/events"
|
||||||
"github.com/docker/docker/pkg/parsers/kernel"
|
"github.com/docker/docker/pkg/parsers/kernel"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/docker/docker/server"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Register(eng *engine.Engine) error {
|
func Register(eng *engine.Engine) error {
|
||||||
|
@ -54,9 +53,6 @@ func remote(eng *engine.Engine) error {
|
||||||
// These components should be broken off into plugins of their own.
|
// These components should be broken off into plugins of their own.
|
||||||
//
|
//
|
||||||
func daemon(eng *engine.Engine) error {
|
func daemon(eng *engine.Engine) error {
|
||||||
if err := eng.Register("initserver", server.InitServer); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return eng.Register("init_networkdriver", bridge.InitDriver)
|
return eng.Register("init_networkdriver", bridge.InitDriver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,12 @@ func (daemon *Daemon) Install(eng *engine.Engine) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := daemon.Repositories().Install(eng); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// FIXME: this hack is necessary for legacy integration tests to access
|
||||||
|
// the daemon object.
|
||||||
|
eng.Hack_SetGlobalVar("httpapi.daemon", daemon)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package daemonconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/docker/daemon/networkdriver"
|
"github.com/docker/docker/daemon/networkdriver"
|
||||||
"github.com/docker/docker/engine"
|
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,46 +33,6 @@ type Config struct {
|
||||||
Sockets []string
|
Sockets []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigFromJob creates and returns a new DaemonConfig object
|
|
||||||
// by parsing the contents of a job's environment.
|
|
||||||
func ConfigFromJob(job *engine.Job) *Config {
|
|
||||||
config := &Config{
|
|
||||||
Pidfile: job.Getenv("Pidfile"),
|
|
||||||
Root: job.Getenv("Root"),
|
|
||||||
AutoRestart: job.GetenvBool("AutoRestart"),
|
|
||||||
EnableIptables: job.GetenvBool("EnableIptables"),
|
|
||||||
EnableIpForward: job.GetenvBool("EnableIpForward"),
|
|
||||||
BridgeIP: job.Getenv("BridgeIP"),
|
|
||||||
BridgeIface: job.Getenv("BridgeIface"),
|
|
||||||
DefaultIp: net.ParseIP(job.Getenv("DefaultIp")),
|
|
||||||
InterContainerCommunication: job.GetenvBool("InterContainerCommunication"),
|
|
||||||
GraphDriver: job.Getenv("GraphDriver"),
|
|
||||||
ExecDriver: job.Getenv("ExecDriver"),
|
|
||||||
EnableSelinuxSupport: job.GetenvBool("EnableSelinuxSupport"),
|
|
||||||
}
|
|
||||||
if graphOpts := job.GetenvList("GraphOptions"); graphOpts != nil {
|
|
||||||
config.GraphOptions = graphOpts
|
|
||||||
}
|
|
||||||
|
|
||||||
if dns := job.GetenvList("Dns"); dns != nil {
|
|
||||||
config.Dns = dns
|
|
||||||
}
|
|
||||||
if dnsSearch := job.GetenvList("DnsSearch"); dnsSearch != nil {
|
|
||||||
config.DnsSearch = dnsSearch
|
|
||||||
}
|
|
||||||
if mtu := job.GetenvInt("Mtu"); mtu != 0 {
|
|
||||||
config.Mtu = mtu
|
|
||||||
} else {
|
|
||||||
config.Mtu = GetDefaultNetworkMtu()
|
|
||||||
}
|
|
||||||
config.DisableNetwork = config.BridgeIface == DisableNetworkBridge
|
|
||||||
if sockets := job.GetenvList("Sockets"); sockets != nil {
|
|
||||||
config.Sockets = sockets
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetDefaultNetworkMtu() int {
|
func GetDefaultNetworkMtu() int {
|
||||||
if iface, err := networkdriver.GetDefaultRouteIface(); err == nil {
|
if iface, err := networkdriver.GetDefaultRouteIface(); err == nil {
|
||||||
return iface.MTU
|
return iface.MTU
|
||||||
|
|
|
@ -7,8 +7,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/docker/docker/builtins"
|
"github.com/docker/docker/builtins"
|
||||||
|
"github.com/docker/docker/daemon"
|
||||||
_ "github.com/docker/docker/daemon/execdriver/lxc"
|
_ "github.com/docker/docker/daemon/execdriver/lxc"
|
||||||
_ "github.com/docker/docker/daemon/execdriver/native"
|
_ "github.com/docker/docker/daemon/execdriver/native"
|
||||||
|
"github.com/docker/docker/daemonconfig"
|
||||||
"github.com/docker/docker/dockerversion"
|
"github.com/docker/docker/dockerversion"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
|
@ -46,27 +48,38 @@ func mainDaemon() {
|
||||||
// the http api so that connections don't fail while the daemon
|
// the http api so that connections don't fail while the daemon
|
||||||
// is booting
|
// is booting
|
||||||
go func() {
|
go func() {
|
||||||
// Load plugin: httpapi
|
// FIXME: daemonconfig and CLI flag parsing should be directly integrated
|
||||||
job := eng.Job("initserver")
|
cfg := &daemonconfig.Config{
|
||||||
// include the variable here too, for the server config
|
Pidfile: *pidfile,
|
||||||
job.Setenv("Pidfile", *pidfile)
|
Root: *flRoot,
|
||||||
job.Setenv("Root", *flRoot)
|
AutoRestart: *flAutoRestart,
|
||||||
job.SetenvBool("AutoRestart", *flAutoRestart)
|
EnableIptables: *flEnableIptables,
|
||||||
job.SetenvList("Dns", flDns.GetAll())
|
EnableIpForward: *flEnableIpForward,
|
||||||
job.SetenvList("DnsSearch", flDnsSearch.GetAll())
|
BridgeIP: *bridgeIp,
|
||||||
job.SetenvBool("EnableIptables", *flEnableIptables)
|
BridgeIface: *bridgeName,
|
||||||
job.SetenvBool("EnableIpForward", *flEnableIpForward)
|
DefaultIp: net.ParseIP(*flDefaultIp),
|
||||||
job.Setenv("BridgeIface", *bridgeName)
|
InterContainerCommunication: *flInterContainerComm,
|
||||||
job.Setenv("BridgeIP", *bridgeIp)
|
GraphDriver: *flGraphDriver,
|
||||||
job.Setenv("DefaultIp", *flDefaultIp)
|
ExecDriver: *flExecDriver,
|
||||||
job.SetenvBool("InterContainerCommunication", *flInterContainerComm)
|
EnableSelinuxSupport: *flSelinuxEnabled,
|
||||||
job.Setenv("GraphDriver", *flGraphDriver)
|
GraphOptions: flGraphOpts.GetAll(),
|
||||||
job.SetenvList("GraphOptions", flGraphOpts.GetAll())
|
Dns: flDns.GetAll(),
|
||||||
job.Setenv("ExecDriver", *flExecDriver)
|
DnsSearch: flDnsSearch.GetAll(),
|
||||||
job.SetenvInt("Mtu", *flMtu)
|
Mtu: *flMtu,
|
||||||
job.SetenvBool("EnableSelinuxSupport", *flSelinuxEnabled)
|
Sockets: flHosts.GetAll(),
|
||||||
job.SetenvList("Sockets", flHosts.GetAll())
|
}
|
||||||
if err := job.Run(); err != nil {
|
// FIXME this should be initialized in NewDaemon or somewhere in daemonconfig.
|
||||||
|
// Currently it is copy-pasted in `integration` to create test daemons that work.
|
||||||
|
if cfg.Mtu == 0 {
|
||||||
|
cfg.Mtu = daemonconfig.GetDefaultNetworkMtu()
|
||||||
|
}
|
||||||
|
cfg.DisableNetwork = cfg.BridgeIface == daemonconfig.DisableNetworkBridge
|
||||||
|
|
||||||
|
d, err := daemon.NewDaemon(cfg, eng)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := d.Install(eng); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
// after the daemon is done setting up we can tell the api to start
|
// after the daemon is done setting up we can tell the api to start
|
||||||
|
@ -75,7 +88,6 @@ func mainDaemon() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// TODO actually have a resolved graphdriver to show?
|
// TODO actually have a resolved graphdriver to show?
|
||||||
log.Printf("docker daemon: %s %s; execdriver: %s; graphdriver: %s",
|
log.Printf("docker daemon: %s %s; execdriver: %s; graphdriver: %s",
|
||||||
dockerversion.VERSION,
|
dockerversion.VERSION,
|
||||||
|
|
|
@ -202,7 +202,7 @@ func spawnHttpsDaemon(addr, cacert, cert, key string) *engine.Engine {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// FIXME: here we don't use NewTestEngine because it calls initserver with Autorestart=false,
|
// FIXME: here we don't use NewTestEngine because it configures the daemon with Autorestart=false,
|
||||||
// and we want to set it to true.
|
// and we want to set it to true.
|
||||||
|
|
||||||
eng := newTestEngine(t, true, root)
|
eng := newTestEngine(t, true, root)
|
||||||
|
|
|
@ -100,7 +100,6 @@ func TestMergeConfigOnCommit(t *testing.T) {
|
||||||
|
|
||||||
func TestRestartKillWait(t *testing.T) {
|
func TestRestartKillWait(t *testing.T) {
|
||||||
eng := NewTestEngine(t)
|
eng := NewTestEngine(t)
|
||||||
srv := mkServerFromEngine(eng, t)
|
|
||||||
runtime := mkDaemonFromEngine(eng, t)
|
runtime := mkDaemonFromEngine(eng, t)
|
||||||
defer runtime.Nuke()
|
defer runtime.Nuke()
|
||||||
|
|
||||||
|
@ -138,9 +137,8 @@ func TestRestartKillWait(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eng = newTestEngine(t, false, runtime.Config().Root)
|
eng = newTestEngine(t, false, runtime.Config().Root)
|
||||||
srv = mkServerFromEngine(eng, t)
|
|
||||||
|
|
||||||
job = srv.Eng.Job("containers")
|
job = eng.Job("containers")
|
||||||
job.SetenvBool("all", true)
|
job.SetenvBool("all", true)
|
||||||
outs, err = job.Stdout.AddListTable()
|
outs, err = job.Stdout.AddListTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -155,7 +153,7 @@ func TestRestartKillWait(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(t, "Waiting on stopped container timedout", 5*time.Second, func() {
|
setTimeout(t, "Waiting on stopped container timedout", 5*time.Second, func() {
|
||||||
job = srv.Eng.Job("wait", outs.Data[0].Get("Id"))
|
job = eng.Job("wait", outs.Data[0].Get("Id"))
|
||||||
if err := job.Run(); err != nil {
|
if err := job.Run(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -164,7 +162,6 @@ func TestRestartKillWait(t *testing.T) {
|
||||||
|
|
||||||
func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
||||||
eng := NewTestEngine(t)
|
eng := NewTestEngine(t)
|
||||||
srv := mkServerFromEngine(eng, t)
|
|
||||||
defer mkDaemonFromEngine(eng, t).Nuke()
|
defer mkDaemonFromEngine(eng, t).Nuke()
|
||||||
|
|
||||||
config, hostConfig, _, err := runconfig.Parse([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
|
config, hostConfig, _, err := runconfig.Parse([]string{"-i", unitTestImageID, "/bin/cat"}, nil)
|
||||||
|
@ -174,7 +171,7 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
||||||
|
|
||||||
id := createTestContainer(eng, config, t)
|
id := createTestContainer(eng, config, t)
|
||||||
|
|
||||||
job := srv.Eng.Job("containers")
|
job := eng.Job("containers")
|
||||||
job.SetenvBool("all", true)
|
job.SetenvBool("all", true)
|
||||||
outs, err := job.Stdout.AddListTable()
|
outs, err := job.Stdout.AddListTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -227,7 +224,7 @@ func TestCreateStartRestartStopStartKillRm(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
job = srv.Eng.Job("containers")
|
job = eng.Job("containers")
|
||||||
job.SetenvBool("all", true)
|
job.SetenvBool("all", true)
|
||||||
outs, err = job.Stdout.AddListTable()
|
outs, err = job.Stdout.AddListTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -17,9 +17,9 @@ import (
|
||||||
|
|
||||||
"github.com/docker/docker/builtins"
|
"github.com/docker/docker/builtins"
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/daemon"
|
||||||
|
"github.com/docker/docker/daemonconfig"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/docker/server"
|
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -153,18 +153,6 @@ func getContainer(eng *engine.Engine, id string, t utils.Fataler) *daemon.Contai
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func mkServerFromEngine(eng *engine.Engine, t utils.Fataler) *server.Server {
|
|
||||||
iSrv := eng.Hack_GetGlobalVar("httpapi.server")
|
|
||||||
if iSrv == nil {
|
|
||||||
panic("Legacy server field not set in engine")
|
|
||||||
}
|
|
||||||
srv, ok := iSrv.(*server.Server)
|
|
||||||
if !ok {
|
|
||||||
panic("Legacy server field in engine does not cast to *server.Server")
|
|
||||||
}
|
|
||||||
return srv
|
|
||||||
}
|
|
||||||
|
|
||||||
func mkDaemonFromEngine(eng *engine.Engine, t utils.Fataler) *daemon.Daemon {
|
func mkDaemonFromEngine(eng *engine.Engine, t utils.Fataler) *daemon.Daemon {
|
||||||
iDaemon := eng.Hack_GetGlobalVar("httpapi.daemon")
|
iDaemon := eng.Hack_GetGlobalVar("httpapi.daemon")
|
||||||
if iDaemon == nil {
|
if iDaemon == nil {
|
||||||
|
@ -191,13 +179,22 @@ func newTestEngine(t utils.Fataler, autorestart bool, root string) *engine.Engin
|
||||||
// Load default plugins
|
// Load default plugins
|
||||||
builtins.Register(eng)
|
builtins.Register(eng)
|
||||||
// (This is manually copied and modified from main() until we have a more generic plugin system)
|
// (This is manually copied and modified from main() until we have a more generic plugin system)
|
||||||
job := eng.Job("initserver")
|
cfg := &daemonconfig.Config{
|
||||||
job.Setenv("Root", root)
|
Root: root,
|
||||||
job.SetenvBool("AutoRestart", autorestart)
|
AutoRestart: autorestart,
|
||||||
job.Setenv("ExecDriver", "native")
|
ExecDriver: "native",
|
||||||
// TestGetEnabledCors and TestOptionsRoute require EnableCors=true
|
}
|
||||||
job.SetenvBool("EnableCors", true)
|
// FIXME: this should be initialized in NewDaemon or somewhere in daemonconfig.
|
||||||
if err := job.Run(); err != nil {
|
// Currently it is copy-pasted from daemonMain()
|
||||||
|
if cfg.Mtu == 0 {
|
||||||
|
cfg.Mtu = daemonconfig.GetDefaultNetworkMtu()
|
||||||
|
}
|
||||||
|
cfg.DisableNetwork = cfg.BridgeIface == daemonconfig.DisableNetworkBridge
|
||||||
|
d, err := daemon.NewDaemon(cfg, eng)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := d.Install(eng); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
return eng
|
return eng
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
Solomon Hykes <solomon@docker.com> (@shykes)
|
|
||||||
Victor Vieux <vieux@docker.com> (@vieux)
|
|
||||||
buildfile.go: Tibor Vass <teabee89@gmail.com> (@tiborvass)
|
|
|
@ -1,62 +0,0 @@
|
||||||
// DEPRECATION NOTICE. PLEASE DO NOT ADD ANYTHING TO THIS FILE.
|
|
||||||
//
|
|
||||||
// For additional commments see server/server.go
|
|
||||||
//
|
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/docker/docker/daemon"
|
|
||||||
"github.com/docker/docker/daemonconfig"
|
|
||||||
"github.com/docker/docker/engine"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (srv *Server) handlerWrap(h engine.Handler) engine.Handler {
|
|
||||||
return func(job *engine.Job) engine.Status {
|
|
||||||
srv.tasks.Add(1)
|
|
||||||
defer srv.tasks.Done()
|
|
||||||
return h(job)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// jobInitApi runs the remote api server `srv` as a daemon,
|
|
||||||
// Only one api server can run at the same time - this is enforced by a pidfile.
|
|
||||||
// The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup.
|
|
||||||
func InitServer(job *engine.Job) engine.Status {
|
|
||||||
job.Logf("Creating server")
|
|
||||||
cfg := daemonconfig.ConfigFromJob(job)
|
|
||||||
srv, err := NewServer(job.Eng, cfg)
|
|
||||||
if err != nil {
|
|
||||||
return job.Error(err)
|
|
||||||
}
|
|
||||||
job.Eng.Hack_SetGlobalVar("httpapi.server", srv)
|
|
||||||
job.Eng.Hack_SetGlobalVar("httpapi.daemon", srv.daemon)
|
|
||||||
|
|
||||||
for name, handler := range map[string]engine.Handler{} {
|
|
||||||
if err := job.Eng.Register(name, srv.handlerWrap(handler)); err != nil {
|
|
||||||
return job.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Install image-related commands from the image subsystem.
|
|
||||||
// See `graph/service.go`
|
|
||||||
if err := srv.daemon.Repositories().Install(job.Eng); err != nil {
|
|
||||||
return job.Error(err)
|
|
||||||
}
|
|
||||||
// Install daemon-related commands from the daemon subsystem.
|
|
||||||
// See `daemon/`
|
|
||||||
if err := srv.daemon.Install(job.Eng); err != nil {
|
|
||||||
return job.Error(err)
|
|
||||||
}
|
|
||||||
return engine.StatusOK
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServer(eng *engine.Engine, config *daemonconfig.Config) (*Server, error) {
|
|
||||||
daemon, err := daemon.NewDaemon(config, eng)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
srv := &Server{
|
|
||||||
Eng: eng,
|
|
||||||
daemon: daemon,
|
|
||||||
}
|
|
||||||
return srv, nil
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
// DEPRECATION NOTICE. PLEASE DO NOT ADD ANYTHING TO THIS FILE.
|
|
||||||
//
|
|
||||||
// server/server.go is deprecated. We are working on breaking it up into smaller, cleaner
|
|
||||||
// pieces which will be easier to find and test. This will help make the code less
|
|
||||||
// redundant and more readable.
|
|
||||||
//
|
|
||||||
// Contributors, please don't add anything to server/server.go, unless it has the explicit
|
|
||||||
// goal of helping the deprecation effort.
|
|
||||||
//
|
|
||||||
// Maintainers, please refuse patches which add code to server/server.go.
|
|
||||||
//
|
|
||||||
// Instead try the following files:
|
|
||||||
// * For code related to local image management, try graph/
|
|
||||||
// * For code related to image downloading, uploading, remote search etc, try registry/
|
|
||||||
// * For code related to the docker daemon, try daemon/
|
|
||||||
// * For small utilities which could potentially be useful outside of Docker, try pkg/
|
|
||||||
// * For miscalleneous "util" functions which are docker-specific, try encapsulating them
|
|
||||||
// inside one of the subsystems above. If you really think they should be more widely
|
|
||||||
// available, are you sure you can't remove the docker dependencies and move them to
|
|
||||||
// pkg? In last resort, you can add them to utils/ (but please try not to).
|
|
||||||
|
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/docker/docker/daemon"
|
|
||||||
"github.com/docker/docker/engine"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
sync.RWMutex
|
|
||||||
daemon *daemon.Daemon
|
|
||||||
Eng *engine.Engine
|
|
||||||
tasks sync.WaitGroup
|
|
||||||
}
|
|
Загрузка…
Ссылка в новой задаче