summaryrefslogtreecommitdiff
path: root/daemon/attach.go
Commit message (Collapse)AuthorAgeFilesLines
* Make it explicit raw|multiplexed stream implementation being usedNicolas De Loof2022-05-121-2/+3
| | | | | | fix #35761 Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
* Replace errors.Cause() with errors.Is() / errors.As()Sebastiaan van Stijn2020-04-291-1/+2
| | | | Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* remove uses of deprecated pkg/termSebastiaan van Stijn2020-04-211-1/+1
| | | | Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* daemon: rename variables that collide with imported package namesSebastiaan van Stijn2020-04-141-13/+13
| | | | Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* daemon.ContainerLogs(): fix resource leak on followKir Kolyshkin2018-09-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When daemon.ContainerLogs() is called with options.follow=true (as in "docker logs --follow"), the "loggerutils.followLogs()" function never returns (even then the logs consumer is gone). As a result, all the resources associated with it (including an opened file descriptor for the log file being read, two FDs for a pipe, and two FDs for inotify watch) are never released. If this is repeated (such as by running "docker logs --follow" and pressing Ctrl-C a few times), this results in DoS caused by either hitting the limit of inotify watches, or the limit of opened files. The only cure is daemon restart. Apparently, what happens is: 1. logs producer (a container) is gone, calling (*LogWatcher).Close() for all its readers (daemon/logger/jsonfilelog/jsonfilelog.go:175). 2. WatchClose() is properly handled by a dedicated goroutine in followLogs(), cancelling the context. 3. Upon receiving the ctx.Done(), the code in followLogs() (daemon/logger/loggerutils/logfile.go#L626-L638) keeps to send messages _synchronously_ (which is OK for now). 4. Logs consumer is gone (Ctrl-C is pressed on a terminal running "docker logs --follow"). Method (*LogWatcher).Close() is properly called (see daemon/logs.go:114). Since it was called before and due to to once.Do(), nothing happens (which is kinda good, as otherwise it will panic on closing a closed channel). 5. A goroutine (see item 3 above) keeps sending log messages synchronously to the logWatcher.Msg channel. Since the channel reader is gone, the channel send operation blocks forever, and resource cleanup set up in defer statements at the beginning of followLogs() never happens. Alas, the fix is somewhat complicated: 1. Distinguish between close from logs producer and logs consumer. To that effect, - yet another channel is added to LogWatcher(); - {Watch,}Close() are renamed to {Watch,}ProducerGone(); - {Watch,}ConsumerGone() are added; *NOTE* that ProducerGone()/WatchProducerGone() pair is ONLY needed in order to stop ConsumerLogs(follow=true) when a container is stopped; otherwise we're not interested in it. In other words, we're only using it in followLogs(). 2. Code that was doing (logWatcher*).Close() is modified to either call ProducerGone() or ConsumerGone(), depending on the context. 3. Code that was waiting for WatchClose() is modified to wait for either ConsumerGone() or ProducerGone(), or both, depending on the context. 4. followLogs() are modified accordingly: - context cancellation is happening on WatchProducerGone(), and once it's received the FileWatcher is closed and waitRead() returns errDone on EOF (i.e. log rotation handling logic is disabled); - due to this, code that was writing synchronously to logWatcher.Msg can be and is removed as the code above it handles this case; - function returns once ConsumerGone is received, freeing all the resources -- this is the bugfix itself. While at it, 1. Let's also remove the ctx usage to simplify the code a bit. It was introduced by commit a69a59ffc7e3d ("Decouple removing the fileWatcher from reading") in order to fix a bug. The bug was actually a deadlock in fsnotify, and the fix was just a workaround. Since then the fsnofify bug has been fixed, and a new fsnotify was vendored in. For more details, please see https://github.com/moby/moby/pull/27782#issuecomment-416794490 2. Since `(*filePoller).Close()` is fixed to remove all the files being watched, there is no need to explicitly call fileWatcher.Remove(name) anymore, so get rid of the extra code. Should fix https://github.com/moby/moby/issues/37391 Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
* Fix fd leak on attachBrian Goff2018-05-311-1/+1
| | | | | | | | | | With a full attach, each attach was leaking 4 goroutines. This updates attach to use errgroup instead of the hodge-podge of waitgroups and channels. In addition, the detach event was never being sent. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
* Add canonical import commentDaniel Nephin2018-02-051-1/+1
| | | | Signed-off-by: Daniel Nephin <dnephin@docker.com>
* Move api/errdefs to errdefsBrian Goff2018-01-111-1/+1
| | | | Signed-off-by: Brian Goff <cpuguy83@gmail.com>
* Add helpers to create errdef errorsBrian Goff2018-01-111-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of having to create a bunch of custom error types that are doing nothing but wrapping another error in sub-packages, use a common helper to create errors of the requested type. e.g. instead of re-implementing this over and over: ```go type notFoundError struct { cause error } func(e notFoundError) Error() string { return e.cause.Error() } func(e notFoundError) NotFound() {} func(e notFoundError) Cause() error { return e.cause } ``` Packages can instead just do: ``` errdefs.NotFound(err) ``` Signed-off-by: Brian Goff <cpuguy83@gmail.com>
* Optimize some wrong usage and spellingwangguoliang2017-09-071-1/+1
| | | | Signed-off-by: wgliang <liangcszzu@163.com>
* Fix golint errors.Daniel Nephin2017-08-181-2/+2
| | | | Signed-off-by: Daniel Nephin <dnephin@docker.com>
* Remove string checking in API error handlingBrian Goff2017-08-151-5/+5
| | | | | | | | | | | | | | Use strongly typed errors to set HTTP status codes. Error interfaces are defined in the api/errors package and errors returned from controllers are checked against these interfaces. Errors can be wraeped in a pkg/errors.Causer, as long as somewhere in the line of causes one of the interfaces is implemented. The special error interfaces take precedence over Causer, meaning if both Causer and one of the new error interfaces are implemented, the Causer is not traversed. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
* Update logrus to v1.0.1Derek McGowan2017-07-311-1/+1
| | | | | | Fixes case sensitivity issue Signed-off-by: Derek McGowan <derek@mcgstyle.net>
* Add a restarting check to ContainerAttachyangshukui2017-05-201-1/+5
| | | | Signed-off-by: yangshukui <yangshukui@huawei.com>
* Update ContainerWait APIJosh Hawn2017-05-161-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds the untilRemoved option to the ContainerWait API which allows the client to wait until the container is not only exited but also removed. This patch also adds some more CLI integration tests for waiting for a created container and waiting with the new --until-removed flag. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Handle detach sequence in CLI Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Update Container Wait Conditions Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Apply container wait changes to API 1.30 The set of changes to the containerWait API missed the cut for the Docker 17.05 release (API version 1.29). This patch bumps the version checks to use 1.30 instead. This patch also makes a minor update to a testfile which was added to the builder/dockerfile package. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Remove wait changes from CLI Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Address minor nits on wait changes - Changed the name of the tty Proxy wrapper to `escapeProxy` - Removed the unnecessary Error() method on container.State - Fixes a typo in comment (repeated word) Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Use router.WithCancel in the containerWait handler This handler previously added this functionality manually but now uses the existing wrapper which does it for us. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Add WaitCondition constants to api/types/container Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Address more ContainerWait review comments - Update ContainerWait backend interface to not return pointer values for container.StateStatus type. - Updated container state's Wait() method comments to clarify that a context MUST be used for cancelling the request, setting timeouts, and to avoid goroutine leaks. - Removed unnecessary buffering when making channels in the client's ContainerWait methods. - Renamed result and error channels in client's ContainerWait methods to clarify that only a single result or error value would be sent on the channel. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Move container.WaitCondition type to separate file ... to avoid conflict with swagger-generated code for API response Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn) Address more ContainerWait review comments Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
* Update Container Wait BackendJosh Hawn2017-05-161-7/+4
| | | | | | | | | | | | | | | | | | | | | This patch consolidates the two WaitStop and WaitWithContext methods on the container.State type. Now there is a single method, Wait, which takes a context and a bool specifying whether to wait for not just a container exit but also removal. The behavior has been changed slightly so that a wait call during a Created state will not return immediately but instead wait for the container to be started and then exited. The interface has been changed to no longer block, but instead returns a channel on which the caller can receive a *StateStatus value which indicates the ExitCode or an error if there was one (like a context timeout or state transition error). These changes have been propagated through the rest of the deamon to preserve all other existing behavior. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
* Close logger only after StartLogger callJim Minter2017-04-201-1/+9
| | | | Signed-off-by: Jim Minter <jminter@redhat.com>
* Fix race on ContainerAttachRawJim Minter2017-04-201-1/+2
| | | | Signed-off-by: Jim Minter <jminter@redhat.com>
* Resolve connection reset by peer regressionJim Minter2017-03-151-2/+6
| | | | Signed-off-by: Jim Minter <jminter@redhat.com>
* invalide detach keys providedlixiaobing100512672017-02-221-1/+1
| | | | Signed-off-by: lixiaobing10051267 <li.xiaobing1@zte.com.cn>
* Resolve race conditions in attach API callJim Minter2017-02-011-51/+49
| | | | Signed-off-by: Jim Minter <jminter@redhat.com>
* Move attach code to stream packageBrian Goff2017-01-231-40/+67
| | | | | | | | | | | This cleans up attach a little bit, and moves it out of the container package. Really `AttachStream` is a method on `*stream.Config`, so moved if from a package level function to one bound to `Config`. In addition, uses a config struct rather than passing around tons and tons of arguments. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
* Move errors/ to api/errorsDaniel Nephin2016-09-161-1/+1
| | | | | | | | | Using: gomvpkg -from github.com/docker/docker/errors -to github.com/docker/docker/api/errors -vcs_mv_cmd "git mv {{.Src}} {{.Dst}}" Signed-off-by: Daniel Nephin <dnephin@docker.com>
* Merge pull request #22777 from WeiZhang555/wait-restartingVincent Demeester2016-06-121-1/+10
|\ | | | | Bug fix: `docker run -i --restart always` hangs
| * Bug fix: `docker run -i --restart always` hangs.Zhang Wei2016-06-061-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | e.g. ``` $ docker run -i --restart always busybox sh pwd / exit 11 <...hang...> ``` This is because Attach(daemon side) and Run(client side) both hangs on WaitStop, if container is restarted too quickly, wait won't have chance to get exit signal. Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
* | Fix logrus formattingYong Tang2016-06-111-1/+1
|/ | | | | | | | | | This fix tries to fix logrus formatting by removing `f` from `logrus.[Error|Warn|Debug|Fatal|Panic|Info]f` when formatting string is not present. This fix fixes #23459. Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
* attach: replace interface with simple typeAlexander Morozov2016-06-031-2/+1
| | | | | | Also add docs to detach events Signed-off-by: Alexander Morozov <lk4d4@docker.com>
* Add detach eventZhang Wei2016-06-031-6/+15
| | | | | | | | | | If we attach to a running container and stream is closed afterwards, we can never be sure if the container is stopped or detached. Adding a new type of `detach` event can explicitly notify client that container is detached, so client will know that there's no need to wait for its exit code and it can move forward to next step now. Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
* Let client print error when speicify wrong detach keysZhang Wei2016-04-041-1/+11
| | | | | | | | | Fix #21064 Let client print error message explicitly when user specifies wrong detach keys. Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
* Remove static errors from errors package.David Calavera2016-02-261-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Moving all strings to the errors package wasn't a good idea after all. Our custom implementation of Go errors predates everything that's nice and good about working with errors in Go. Take as an example what we have to do to get an error message: ```go func GetErrorMessage(err error) string { switch err.(type) { case errcode.Error: e, _ := err.(errcode.Error) return e.Message case errcode.ErrorCode: ec, _ := err.(errcode.ErrorCode) return ec.Message() default: return err.Error() } } ``` This goes against every good practice for Go development. The language already provides a simple, intuitive and standard way to get error messages, that is calling the `Error()` method from an error. Reinventing the error interface is a mistake. Our custom implementation also makes very hard to reason about errors, another nice thing about Go. I found several (>10) error declarations that we don't use anywhere. This is a clear sign about how little we know about the errors we return. I also found several error usages where the number of arguments was different than the parameters declared in the error, another clear example of how difficult is to reason about errors. Moreover, our custom implementation didn't really make easier for people to return custom HTTP status code depending on the errors. Again, it's hard to reason about when to set custom codes and how. Take an example what we have to do to extract the message and status code from an error before returning a response from the API: ```go switch err.(type) { case errcode.ErrorCode: daError, _ := err.(errcode.ErrorCode) statusCode = daError.Descriptor().HTTPStatusCode errMsg = daError.Message() case errcode.Error: // For reference, if you're looking for a particular error // then you can do something like : // import ( derr "github.com/docker/docker/errors" ) // if daError.ErrorCode() == derr.ErrorCodeNoSuchContainer { ... } daError, _ := err.(errcode.Error) statusCode = daError.ErrorCode().Descriptor().HTTPStatusCode errMsg = daError.Message default: // This part of will be removed once we've // converted everything over to use the errcode package // FIXME: this is brittle and should not be necessary. // If we need to differentiate between different possible error types, // we should create appropriate error types with clearly defined meaning errStr := strings.ToLower(err.Error()) for keyword, status := range map[string]int{ "not found": http.StatusNotFound, "no such": http.StatusNotFound, "bad parameter": http.StatusBadRequest, "conflict": http.StatusConflict, "impossible": http.StatusNotAcceptable, "wrong login/password": http.StatusUnauthorized, "hasn't been activated": http.StatusForbidden, } { if strings.Contains(errStr, keyword) { statusCode = status break } } } ``` You can notice two things in that code: 1. We have to explain how errors work, because our implementation goes against how easy to use Go errors are. 2. At no moment we arrived to remove that `switch` statement that was the original reason to use our custom implementation. This change removes all our status errors from the errors package and puts them back in their specific contexts. IT puts the messages back with their contexts. That way, we know right away when errors used and how to generate their messages. It uses custom interfaces to reason about errors. Errors that need to response with a custom status code MUST implementent this simple interface: ```go type errorWithStatus interface { HTTPErrorStatusCode() int } ``` This interface is very straightforward to implement. It also preserves Go errors real behavior, getting the message is as simple as using the `Error()` method. I included helper functions to generate errors that use custom status code in `errors/errors.go`. By doing this, we remove the hard dependency we have eeverywhere to our custom errors package. Yes, you can use it as a helper to generate error, but it's still very easy to generate errors without it. Please, read this fantastic blog post about errors in Go: http://dave.cheney.net/2014/12/24/inspecting-errors Signed-off-by: David Calavera <david.calavera@gmail.com>
* cleanup attach api callsBrian Goff2016-02-091-38/+11
| | | | Signed-off-by: Brian Goff <cpuguy83@gmail.com>
* Move backend types to their own package.David Calavera2016-02-081-2/+2
| | | | | | - Remove duplicated structs that we already have in engine-api. Signed-off-by: David Calavera <david.calavera@gmail.com>
* Decouple the "container" router from the actual daemon implementation.Lukas Waslowski2016-02-081-24/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is done by moving the following types to api/types/config.go: - ContainersConfig - ContainerAttachWithLogsConfig - ContainerWsAttachWithLogsConfig - ContainerLogsConfig - ContainerStatsConfig Remove dependency on "version" package from types.ContainerStatsConfig. Decouple the "container" router from the "daemon/exec" implementation. * This is done by making daemon.ContainerExecInspect() return an interface{} value. The same trick is already used by daemon.ContainerInspect(). Improve documentation for router packages. Extract localRoute and router into separate files. Move local.router to image.imageRouter. Changes: - Move local/image.go to image/image_routes.go. - Move local/local.go to image/image.go - Rename router to imageRouter. - Simplify imports for image/image.go (remove alias for router package). Merge router/local package into router package. Decouple the "image" router from the actual daemon implementation. Add Daemon.GetNetworkByID and Daemon.GetNetworkByName. Decouple the "network" router from the actual daemon implementation. This is done by replacing the daemon.NetworkByName constant with an explicit GetNetworkByName method. Remove the unused Daemon.GetNetwork method and the associated constants NetworkByID and NetworkByName. Signed-off-by: Lukas Waslowski <cr7pt0gr4ph7@gmail.com> Signed-off-by: David Calavera <david.calavera@gmail.com>
* Remove package daemonbuilder.Anusha Ragunathan2016-02-011-0/+10
| | | | | | | | | | | | | Currently, daemonbuilder package (part of daemon) implemented the builder backend. However, it was a very thin wrapper around daemon methods and caused an implementation dependency for api/server build endpoint. api/server buildrouter should only know about the backend implementing the /build API endpoint. Removing daemonbuilder involved moving build specific methods to respective files in the daemon, where they fit naturally. Signed-off-by: Anusha Ragunathan <anusha@docker.com>
* Implement configurable detach keyVincent Demeester2016-01-031-11/+13
| | | | | | | | | | | | Implement configurable detach keys (for `attach`, exec`, `run` and `start`) using the client-side configuration - Adds a `--detach-keys` flag to `attach`, `exec`, `run` and `start` commands. - Adds a new configuration field (in `~/.docker/config.json`) to configure the default escape keys for docker client. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
* Remove `IsPaused` from backend interface.David Calavera2015-12-211-10/+41
| | | | | | Move connection hijacking logic to the daemon. Signed-off-by: David Calavera <david.calavera@gmail.com>
* Rename `Daemon.Get` to `Daemon.GetContainer`.David Calavera2015-12-111-2/+2
| | | | | | This is more aligned with `Daemon.GetImage` and less confusing. Signed-off-by: David Calavera <david.calavera@gmail.com>
* Move Container to its own package.David Calavera2015-12-031-1/+2
| | | | | | | | So other packages don't need to import the daemon package when they want to use this struct. Signed-off-by: David Calavera <david.calavera@gmail.com> Signed-off-by: Tibor Vass <tibor@docker.com>
* Decouple daemon and container to configure logging drivers.David Calavera2015-11-041-1/+1
| | | | Signed-off-by: David Calavera <david.calavera@gmail.com>
* Decouple daemon and container to log events.David Calavera2015-11-041-2/+61
| | | | | | Create a supervisor interface to let the container monitor to emit events. Signed-off-by: David Calavera <david.calavera@gmail.com>
* Revert "Merge pull request #16228 from duglin/ContextualizeEvents"Tibor Vass2015-09-291-7/+6
| | | | | | | | | | | | | | | | | | | | | Although having a request ID available throughout the codebase is very valuable, the impact of requiring a Context as an argument to every function in the codepath of an API request, is too significant and was not properly understood at the time of the review. Furthermore, mixing API-layer code with non-API-layer code makes the latter usable only by API-layer code (one that has a notion of Context). This reverts commit de4164043546d2b9ee3bf323dbc41f4979c84480, reversing changes made to 7daeecd42d7bb112bfe01532c8c9a962bb0c7967. Signed-off-by: Tibor Vass <tibor@docker.com> Conflicts: api/server/container.go builder/internals.go daemon/container_unix.go daemon/create.go
* Fix comment typo in attach.goLei Jitang2015-09-281-1/+1
| | | | Signed-off-by: Lei Jitang <leijitang@huawei.com>
* Add context.RequestID to event streamDoug Davis2015-09-241-6/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | This PR adds a "request ID" to each event generated, the 'docker events' stream now looks like this: ``` 2015-09-10T15:02:50.000000000-07:00 [reqid: c01e3534ddca] de7c5d4ca927253cf4e978ee9c4545161e406e9b5a14617efb52c658b249174a: (from ubuntu) create ``` Note the `[reqID: c01e3534ddca]` part, that's new. Each HTTP request will generate its own unique ID. So, if you do a `docker build` you'll see a series of events all with the same reqID. This allow for log processing tools to determine which events are all related to the same http request. I didn't propigate the context to all possible funcs in the daemon, I decided to just do the ones that needed it in order to get the reqID into the events. I'd like to have people review this direction first, and if we're ok with it then I'll make sure we're consistent about when we pass around the context - IOW, make sure that all funcs at the same level have a context passed in even if they don't call the log funcs - this will ensure we're consistent w/o passing it around for all calls unnecessarily. ping @icecrime @calavera @crosbymichael Signed-off-by: Doug Davis <dug@us.ibm.com>
* refactor attach to not use internal data structuresMorgan Bauer2015-09-231-2/+11
| | | | | | - refactor to make it easier to split the api in the future Signed-off-by: Morgan Bauer <mbauer@us.ibm.com>
* golint fixes for daemon/ packageMorgan Bauer2015-08-271-2/+7
| | | | | | | | | | | | - some method names were changed to have a 'Locking' suffix, as the downcased versions already existed, and the existing functions simply had locks around the already downcased version. - deleting unused functions - package comment - magic numbers replaced by golang constants - comments all over Signed-off-by: Morgan Bauer <mbauer@us.ibm.com>
* Fix regression in containers attach/wsattach api, return not found before ↵Antonio Murdaca2015-07-011-12/+2
| | | | | | hijacking Signed-off-by: Antonio Murdaca <runcom@linux.com>
* Remove missed code path for api < 1.12Antonio Murdaca2015-06-171-2/+1
| | | | Signed-off-by: Antonio Murdaca <runcom@linux.com>
* Move container.WaitStop, AttachWithLogs and WsAttachWithLogs to daemon ↵Antonio Murdaca2015-05-111-207/+39
| | | | | | service in api server Signed-off-by: Antonio Murdaca <me@runcom.ninja>
* Refactor utils/utils, fixes #11923Antonio Murdaca2015-04-141-2/+44
| | | | Signed-off-by: Antonio Murdaca <me@runcom.ninja>
* Fix regressions in attachAlexander Morozov2015-04-091-7/+9
| | | | | | | | | * Wrong bool parsing * Attach always all streams Were introduced in #12120 Signed-off-by: Alexander Morozov <lk4d4@docker.com>