-
Notifications
You must be signed in to change notification settings - Fork 18.9k
libcontainerd: split client and daemon supervision #37149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,7 +36,7 @@ import ( | |
| "github.com/docker/docker/daemon/config" | ||
| "github.com/docker/docker/daemon/listeners" | ||
| "github.com/docker/docker/dockerversion" | ||
| "github.com/docker/docker/libcontainerd" | ||
| "github.com/docker/docker/libcontainerd/supervisor" | ||
| dopts "github.com/docker/docker/opts" | ||
| "github.com/docker/docker/pkg/authorization" | ||
| "github.com/docker/docker/pkg/jsonmessage" | ||
|
|
@@ -45,7 +45,6 @@ import ( | |
| "github.com/docker/docker/pkg/signal" | ||
| "github.com/docker/docker/pkg/system" | ||
| "github.com/docker/docker/plugin" | ||
| "github.com/docker/docker/registry" | ||
| "github.com/docker/docker/runconfig" | ||
| "github.com/docker/go-connections/tlsconfig" | ||
| swarmapi "github.com/docker/swarmkit/api" | ||
|
|
@@ -112,6 +111,10 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { | |
| return err | ||
| } | ||
|
|
||
| if err := system.MkdirAll(cli.Config.ExecRoot, 0700, ""); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if cli.Pidfile != "" { | ||
| pf, err := pidfile.New(cli.Pidfile) | ||
| if err != nil { | ||
|
|
@@ -135,19 +138,27 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { | |
| return fmt.Errorf("Failed to load listeners: %v", err) | ||
| } | ||
|
|
||
| registryService, err := registry.NewService(cli.Config.ServiceOptions) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| ctx, cancel := context.WithCancel(context.Background()) | ||
| if cli.Config.ContainerdAddr == "" && runtime.GOOS != "windows" { | ||
| opts, err := cli.getContainerdDaemonOpts() | ||
| if err != nil { | ||
| cancel() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like if you move ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
 if cli.Config.ContainerdAddr == "" && runtime.GOOS != "windows" {
 opts, err := cli.getContainerdDaemonOpts()
 if err != nil {
- cancel()
 return fmt.Errorf("Failed to generate containerd options: %v", err)
 }
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is actually like this on purpose, the defer ordering is important because the |
||
| return fmt.Errorf("Failed to generate containerd options: %v", err) | ||
| } | ||
|
|
||
| rOpts, err := cli.getRemoteOptions() | ||
| if err != nil { | ||
| return fmt.Errorf("Failed to generate containerd options: %v", err) | ||
| } | ||
| containerdRemote, err := libcontainerd.New(filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), rOpts...) | ||
| if err != nil { | ||
| return err | ||
| r, err := supervisor.Start(ctx, filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), opts...) | ||
| if err != nil { | ||
| cancel() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
| return fmt.Errorf("Failed to start containerd: %v", err) | ||
| } | ||
|
|
||
| cli.Config.ContainerdAddr = r.Address() | ||
|
|
||
| // Try to wait for containerd to shutdown | ||
| defer r.WaitTimeout(10 * time.Second) | ||
| } | ||
| defer cancel() | ||
|
|
||
| signal.Trap(func() { | ||
| cli.stop() | ||
| <-stopc // wait for daemonCli.start() to return | ||
|
|
@@ -162,7 +173,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { | |
| logrus.Fatalf("Error creating middlewares: %v", err) | ||
| } | ||
|
|
||
| d, err := daemon.NewDaemon(cli.Config, registryService, containerdRemote, pluginStore) | ||
| d, err := daemon.NewDaemon(ctx, cli.Config, pluginStore) | ||
| if err != nil { | ||
| return fmt.Errorf("Error starting daemon: %v", err) | ||
| } | ||
|
|
@@ -207,10 +218,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { | |
|
|
||
| initRouter(routerOptions) | ||
|
|
||
| // process cluster change notifications | ||
| watchCtx, cancel := context.WithCancel(context.Background()) | ||
| defer cancel() | ||
| go d.ProcessClusterNotifications(watchCtx, c.GetWatchStream()) | ||
| go d.ProcessClusterNotifications(ctx, c.GetWatchStream()) | ||
|
|
||
| cli.setupConfigReloadTrap() | ||
|
|
||
|
|
@@ -227,8 +235,12 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { | |
| // Wait for serve API to complete | ||
| errAPI := <-serveAPIWait | ||
| c.Cleanup() | ||
|
|
||
| shutdownDaemon(d) | ||
| containerdRemote.Cleanup() | ||
|
|
||
| // Stop notification processing and any background processes | ||
| cancel() | ||
|
|
||
| if errAPI != nil { | ||
| return fmt.Errorf("Shutting down due to ServeAPI error: %v", errAPI) | ||
| } | ||
|
|
@@ -511,14 +523,22 @@ func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config | |
| return nil | ||
| } | ||
|
|
||
| func (cli *DaemonCli) getRemoteOptions() ([]libcontainerd.RemoteOption, error) { | ||
| opts := []libcontainerd.RemoteOption{} | ||
|
|
||
| pOpts, err := cli.getPlatformRemoteOptions() | ||
| func (cli *DaemonCli) getContainerdDaemonOpts() ([]supervisor.DaemonOpt, error) { | ||
| opts, err := cli.getPlatformContainerdDaemonOpts() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| opts = append(opts, pOpts...) | ||
|
|
||
| if cli.Config.Debug { | ||
| opts = append(opts, supervisor.WithLogLevel("debug")) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we use
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like you addressed this based on the last rebase |
||
| } else if cli.Config.LogLevel != "" { | ||
| opts = append(opts, supervisor.WithLogLevel(cli.Config.LogLevel)) | ||
| } | ||
|
|
||
| if !cli.Config.CriContainerd { | ||
| opts = append(opts, supervisor.WithPlugin("cri", nil)) | ||
| } | ||
|
|
||
| return opts, nil | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks new; where/when was this directory created in the past?
I also see some validations steps below that may fail; is it possible to move this further down, so that we don't end up with this directory if the configuration happened to be invalid?
Finally; not sure if this directory needs special treatment (as the "daemon" root gets); also taking into account that this code is both Linux and Windows (and Windows doesn't handle permissions similar to Linux)
moby/daemon/daemon_unix.go
Lines 1136 to 1187 in 8e2f920
moby/daemon/daemon_windows.go
Lines 472 to 479 in 6cd806a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously this directory was getting created as a side effect of getting a containerd client. This seemed to be an inappropriate way to create a shared directory so I just moved it here. It is still getting created with same permissions at roughly the same time though.