Commit Graph

29 Commits

Author SHA1 Message Date
Paweł Gronowski
62ed24a87c modernize: Use slices.Contains
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-15 18:56:34 +01:00
Sebastiaan van Stijn
0af2962fdd daemon: reduce use of pointer-slices in backend
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-13 20:52:15 +01:00
Cory Snider
778e5bfad3 api/types/filters: move to daemon/internal
Most of the code in the filters package relates to the unmarshaling,
validation and application of filters from client requests. None of this
is necessary or particularly useful for Go SDK users. Move the full-fat
filters package into daemon/internal and switch all the daemon code to
import that package so we are free to iterate upon the code without
worrying about source-code interface compatibility.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2025-10-08 12:06:26 -04:00
Sebastiaan van Stijn
0df791cb72 explicitly access Container.State instead of through embedded struct
The Container.State struct holds the container's state, and most of
its fields are expected to change dynamically. Some o these state-changes
are explicit, for example, setting the container to be "stopped". Other
state changes can be more explicit, for example due to the containers'
process exiting or being "OOM" killed by the kernel.

The distinction between explicit ("desired") state changes and "state"
("actual state") is sometimes vague; for some properties, we clearly
separated them, for example if a user requested the container to be
stopped or restarted, we store state in the Container object itself;

    HasBeenManuallyStopped   bool // used for unless-stopped restart policy
    HasBeenManuallyRestarted bool `json:"-"` // used to distinguish restart caused by restart policy from the manual one

Other properties are more ambiguous. such as "HasBeenStartedBefore" and
"RestartCount", which are stored on the Container (and persisted to
disk), but may be more related to "actual" state, and likely should
not be persisted;

    RestartCount             int
    HasBeenStartedBefore     bool

Given that (per the above) concurrency must be taken into account, most
changes to the `container.State` struct should be protected; here's where
things get blurry. While the `State` type provides various accessor methods,
only some of them take concurrency into account; for example, [State.IsRunning]
and [State.GetPID] acquire a lock, whereas [State.ExitCodeValue] does not.
Even the (commonly used) [State.StateString] has no locking at all.

The way to handle this is error-prone; [container.State] contains a mutex,
and it's exported. Given that its embedded in the [container.Container]
struct, it's also exposed as an exported mutex for the container. The
assumption here is that by "merging" the two, the caller to acquire a lock
when either the container _or_ its state must be mutated. However, because
some methods on `container.State` handle their own locking, consumers must
be deeply familiar with the internals; if both changes to the `Container`
AND `Container.State` must be made. This gets amplified more as some
(exported!) methods, such as [container.SetRunning] mutate multiple fields,
but don't acquire a lock (so expect the caller to hold one), but their
(also exported) counterpart (e.g. [State.IsRunning]) do.

It should be clear from the above, that this needs some architectural
changes; a clearer separation between "desired" and "actual" state (opening
the potential to update the container's config without manually touching
its `State`), possibly a method to obtain a read-only copy of the current
state (for those querying state), and reviewing which fields belong where
(and should be persisted to disk, or only remain in memory).

This PR preserves the status quo; it makes no structural changes, other
than exposing where we access the container's state. Where previously the
State fields and methods were referred to as "part of the container"
(e.g. `ctr.IsRunning()` or `ctr.Running`), we now explicitly reference
the embedded `State` (`ctr.State.IsRunning`, `ctr.State.Running`).

The exception (for now) is the mutex, which is still referenced through
the embedded struct (`ctr.Lock()` instead of `ctr.State.Lock()`), as this
is (mostly) by design to protect the container, and what's in it (including
its `State`).

[State.IsRunning]: c4afa77157/daemon/container/state.go (L205-L209)
[State.GetPID]: c4afa77157/daemon/container/state.go (L211-L216)
[State.ExitCodeValue]: c4afa77157/daemon/container/state.go (L218-L228)
[State.StateString]: c4afa77157/daemon/container/state.go (L102-L131)
[container.State]: c4afa77157/daemon/container/state.go (L15-L23)
[container.Container]: c4afa77157/daemon/container/container.go (L67-L75)
[container.SetRunning]: c4afa77157/daemon/container/state.go (L230-L277)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-19 16:02:14 +02:00
Sebastiaan van Stijn
4d20b6fe56 api/types/container: move container options to client
Move the option-types to the client and in some cases create a
copy for the backend. These types are used to construct query-
args, and not marshaled to JSON, and can be replaced with functional
options in the client.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-04 20:09:55 +02:00
Derek McGowan
f74e5d48b3 Create github.com/moby/moby/v2 module
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-07-31 10:13:29 -07:00
Derek McGowan
f24455c90b Move image to daemon/internal/image
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-07-24 12:11:02 -07:00
Derek McGowan
afd6487b2e Create github.com/moby/moby/api module
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-07-21 09:30:05 -07:00
Derek McGowan
5419eb1efc Move container to daemon/container
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-06-27 14:27:21 -07:00
Sebastiaan van Stijn
a8f14e06d6 Improve performance of daemon.Containers().
Improve performance of function daemon.Containers() (used by docker ps) to
mitigate a latency increase when running large number of containers using the
containerd image store.

We do this by refactoring daemon.Containers() to collect info for containers in
parallel, rather than sequentially, using up to log2(N) worker threads. This
improves the performance from O(N) to O(log2(N)), where N is the number of
containers.

To verify correctness, this commits adds unit and integration tests.

Signed-off-by: Cesar Talledo <cesar.talledo@docker.com>
2025-03-12 09:59:52 -07:00
Aleksa Sarai
0553d3d994 tests: migrate away from assert.Assert(err == nil)
Unfortunately, gofmt doesn't know about types so it was necessary to
find all of the err == nil statements through trial and error. Note that
there is no is.NilError, so for assert.Check(t, err == nil) we need to
switch to just doing assert.Check(t, err). If err is an error type, this
is equivalent (and there isn't another trivial way of doing it). Here
are the full set of rules used:

Generic "err == nil":

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, err == nil) -> assert.NilError(t, err)"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, err == nil) -> assert.Check(t, err)"

Generic, but with a different variable name:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, sr.err == nil) -> assert.NilError(t, sr.err)"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, sr.err == nil) -> assert.Check(t, sr.err)"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, err2 == nil) -> assert.NilError(t, err2)"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, err2 == nil) -> assert.Check(t, err2)"

JSON-related error assertions:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, json.Unmarshal(a, b) == nil) -> assert.NilError(t, json.Unmarshal(a, b))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, json.Unmarshal(a, b) == nil) -> assert.Check(t, json.Unmarshal(a, b))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, json.NewDecoder(a).Decode(b) == nil) -> assert.NilError(t, json.NewDecoder(a).Decode(b))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, json.NewDecoder(a).Decode(b) == nil) -> assert.Check(t, json.NewDecoder(a).Decode(b))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, json.NewEncoder(a).Encode(b) == nil) -> assert.NilError(t, json.NewEncoder(a).Encode(b))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, json.NewEncoder(a).Encode(b) == nil) -> assert.Check(t, json.NewEncoder(a).Encode(b))"

Process-related error assertions:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, a.Start() == nil) -> assert.NilError(t, a.Start())"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, a.Start() == nil) -> assert.Check(t, a.Start())"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, a.Kill() == nil) -> assert.NilError(t, a.Kill())"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, a.Kill() == nil) -> assert.Check(t, a.Kill())"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, a.Signal(b) == nil) -> assert.NilError(t, a.Signal(b))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, a.Signal(b) == nil) -> assert.Check(t, a.Signal(b))"

waitInspect:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, waitInspect(a, b, c, d) == nil) -> assert.NilError(t, waitInspect(a, b, c, d))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, waitInspect(a, b, c, d) == nil) -> assert.Check(t, waitInspect(a, b, c, d))"

File closing error assertions:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, a.Close() == nil) -> assert.NilError(t, a.Close())"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, a.Close() == nil) -> assert.Check(t, a.Close())"

mount.MakeRShared:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, mount.MakeRShared(a) == nil) -> assert.NilError(t, mount.MakeRShared(a))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, mount.MakeRShared(a) == nil) -> assert.Check(t, mount.MakeRShared(a))"

daemon.SwarmLeave:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, d.SwarmLeave(a, b, c) == nil) -> assert.NilError(t, d.SwarmLeave(a, b, c))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, d.SwarmLeave(a, b, c) == nil) -> assert.Check(t, d.SwarmLeave(a, b, c))"

os.MkdirAll:

  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Assert(t, os.MkdirAll(a, b) == nil) -> assert.NilError(t, os.MkdirAll(a, b))"
  find . -type f -name "*_test.go" | \
    xargs gofmt -w -r "assert.Check(t, os.MkdirAll(a, b) == nil) -> assert.Check(t, os.MkdirAll(a, b))"

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2024-11-22 23:59:20 +11:00
Sebastiaan van Stijn
05b0e653dd api/types: move Container to api/types/container
This moves the `Container` type to the containere package, rename
it to `Summary`, and deprecates the old location.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-02 12:46:48 +02:00
Sebastiaan van Stijn
9670d9364d api/types: move ContainerListOptions to api/types/container
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-12 11:29:24 +02:00
Sebastiaan van Stijn
210932b3bf daemon: format code with gofumpt
Formatting the code with https://github.com/mvdan/gofumpt

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-06-29 00:33:03 +02:00
Sebastiaan van Stijn
5bc0832766 daemon: inline filters in tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-04-25 15:13:26 +02:00
Sebastiaan van Stijn
456ea1bb1d image: deprecate IDFromDigest()
Having this function hides what it's doing, which is just to type-cast
to an image.ID (which is a digest). Using a cast is more transparent,
so deprecating this function in favor of a regular typecast.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-01 12:33:00 +01:00
Nicolas De Loof
def549c8f6 imageservice: Add context to various methods
Co-authored-by: Paweł Gronowski <pawel.gronowski@docker.com>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2022-11-03 12:22:40 +01:00
Sebastiaan van Stijn
bdb878ab2c filters: lowercase error
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-03-18 09:44:53 +01:00
Sebastiaan van Stijn
a0230f3d9a remove unneeded "digest" alias for "go-digest"
I think this was there for historic reasons (may have been goimports expected
this, and we used to have a linter that wanted it), but it's not needed, so
let's remove it (to make my IDE less complaining about unneeded aliases).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-03-04 14:49:42 +01:00
Eng Zer Jun
c55a4ac779 refactor: move from io/ioutil to io and os package
The io/ioutil package has been deprecated in Go 1.16. This commit
replaces the existing io/ioutil functions with their new definitions in
io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-08-27 14:56:57 +08:00
Sebastiaan van Stijn
eb14d936bf daemon: rename variables that collide with imported package names
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-04-14 17:22:23 +02:00
Sebastiaan van Stijn
9f0b3f5609 bump gotest.tools v3.0.1 for compatibility with Go 1.14
full diff: https://github.com/gotestyourself/gotest.tools/compare/v2.3.0...v3.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-02-11 00:06:42 +01:00
Sebastiaan van Stijn
07ff4f1de8 goimports: fix imports
Format the source according to latest goimports.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-09-18 12:56:54 +02:00
Justin Cormack
c435551ccc Switch to google/uuid
pborman/uuid and google/uuid used to be different versions of
the same package, but now pborman/uuid is a compatibility wrapper
around google/uuid, maintained by the same person.

Clean up some of the usage as the functions differ slightly.

Not yet removed some uses of pborman/uuid in vendored code but
I have PRs in process for these.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
2019-03-13 14:13:58 +00:00
Sebastiaan van Stijn
6f9b5ba810 Fix regression when filtering container names using a leading slash
Commit 5c8da2e967 updated the filtering behavior
to match container-names without having to specify the leading slash.

This change caused a regression in situations where a regex was provided as
filter, using an explicit leading slash (`--filter name=^/mycontainername`).

This fix changes the filters to match containers both with, and without the
leading slash, effectively making the leading slash optional when filtering.

With this fix, filters with and without a leading slash produce the same result:

    $ docker ps --filter name=^a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    21afd6362b0c        busybox             "sh"                2 minutes ago       Up 2 minutes                            a2
    56e53770e316        busybox             "sh"                2 minutes ago       Up 2 minutes                            a1

    $ docker ps --filter name=^/a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    21afd6362b0c        busybox             "sh"                2 minutes ago       Up 2 minutes                            a2
    56e53770e316        busybox             "sh"                3 minutes ago       Up 3 minutes                            a1

    $ docker ps --filter name=^b
    CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
    b69003b6a6fe        busybox             "sh"                About a minute ago   Up About a minute                       b1

    $ docker ps --filter name=^/b
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    b69003b6a6fe        busybox             "sh"                56 seconds ago      Up 54 seconds                           b1

    $ docker ps --filter name=/a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    21afd6362b0c        busybox             "sh"                3 minutes ago       Up 3 minutes                            a2
    56e53770e316        busybox             "sh"                4 minutes ago       Up 4 minutes                            a1

    $ docker ps --filter name=a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    21afd6362b0c        busybox             "sh"                3 minutes ago       Up 3 minutes                            a2
    56e53770e316        busybox             "sh"                4 minutes ago       Up 4 minutes                            a1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-08-28 21:40:13 +02:00
Chris White
5c8da2e967 Remove slash prefix when matching name filters (Fixes #37453)
* Regex name filters were display undesired behavior due to
  names containing the trailing slash when being compared
* Adjusted filterByNameIDMatches and includeContainerInList to
  strip the slash prefix before doing name comparisons
* Added test case and helper functions for the test to list_test
* Force failed tests during development to ensure there were
  no false positives

Signed-off-by: Chris White <me@cwprogram.com>
2018-07-15 05:57:29 -05:00
Vincent Demeester
3845728524 Update tests to use gotest.tools 👼
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-06-13 09:04:30 +02:00
Vincent Demeester
641c73d211 Clean some cli-only integration tests
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-02-19 11:19:19 +01:00
Vincent Demeester
05e7f2cf58 Test invalid filter and move validation on top
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-02-15 16:24:26 +01:00