Skip to content

Add container inspect storage field#50857

Merged
thaJeztah merged 1 commit intomoby:masterfrom
austinvazquez:add-container-inspect-storage-driver
Sep 26, 2025
Merged

Add container inspect storage field#50857
thaJeztah merged 1 commit intomoby:masterfrom
austinvazquez:add-container-inspect-storage-driver

Conversation

@austinvazquez
Copy link
Contributor

@austinvazquez austinvazquez commented Aug 29, 2025

- What I did
Implements #50812

This change adds new storage API type designed to be more extensible with a name field. This is to enable a single Storage field in container inspect responses each for containerd snapshotter backed container/images.

- How I did it

- How to verify it

- Human readable description for the release notes

api/types/storage: add `Storage` type and integrate in container inspect

- A picture of a cute animal (not mandatory but encouraged)

@austinvazquez austinvazquez added this to the 29.0.0 milestone Aug 29, 2025
@austinvazquez austinvazquez added area/api API kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. impact/api area/daemon Core Engine release-blocker PRs we want to block a release on labels Aug 29, 2025
@austinvazquez austinvazquez self-assigned this Aug 29, 2025
@austinvazquez austinvazquez force-pushed the add-container-inspect-storage-driver branch from 31251b3 to 377b375 Compare August 29, 2025 22:22
api/swagger.yaml Outdated
Type:
description: "Type of storage driver."
type: "string"
enum: ["snapshotter", "graph-driver"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm considering we could keep the GraphDriver .. for graphdrivers, and omit the GraphDriver field entirely when snapshotters are used..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thaJeztah , I assume then when using graph drivers StorageDriver would be omitted, wdyt?

api/swagger.yaml Outdated
Comment on lines +1898 to +1901
example: {
"MergedDir": "/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/merged",
"UpperDir": "/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/diff",
"WorkDir": "/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/work"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... in that case we don't necessarily have to adopt this information; or at least we need to consider if this is information that's we want to expose.

The current inspect output contains various paths that are effectively an internal implementation detail, which includes some paths for files used as internal storage mechanism, e.g.;

        "ResolvConfPath": "/var/lib/docker/containers/21d2ca40cfb4fa05f8f267a6fc6c0ecfa36d9fe046ec7ed896570cb28b0dc867/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/21d2ca40cfb4fa05f8f267a6fc6c0ecfa36d9fe046ec7ed896570cb28b0dc867/hostname",
        "HostsPath": "/var/lib/docker/containers/21d2ca40cfb4fa05f8f267a6fc6c0ecfa36d9fe046ec7ed896570cb28b0dc867/hosts",
        "LogPath": "/var/lib/docker/containers/21d2ca40cfb4fa05f8f267a6fc6c0ecfa36d9fe046ec7ed896570cb28b0dc867/21d2ca40cfb4fa05f8f267a6fc6c0ecfa36d9fe046ec7ed896570cb28b0dc867-json.log",

Those paths were added "because it was simple to add them, so why not?", but because they were exposed somewhat indicated that it's OK to access, and "invited" users to start using those paths to their liking.

  • tools scraping those log-files and/or rotating them
  • users modifying the filenames on the host
  • users modifying the container filesystem on the host

And the reverse; users with Docker Desktop on macOS or Windows being confused "that path doesn't exist on my host.. where is it?

@austinvazquez austinvazquez force-pushed the add-container-inspect-storage-driver branch from 377b375 to d14087d Compare August 30, 2025 00:06
@austinvazquez austinvazquez marked this pull request as ready for review August 30, 2025 01:17
@austinvazquez austinvazquez requested a review from tianon as a code owner August 30, 2025 01:17

// StorageDriver holds information about the storage driver used to store the
// container's and image's filesystem.
StorageDriver storage.Driver `json:"StorageDriver,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is future proof, containerd can use multiple storage drivers, one may just be the default

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is for image inspect; you mean an image that is present in multiple snapshotters?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For images, it could be unpacked into zero or more snapshotter. If we want to start favoring the content store as the source of truth for image storage and treat the snapshotter as a cached of the unpacked value, then it may be confusing to generically say this is how the image is "stored".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, so we either should omit it entirely, or go all the way and enumerate all snapshots.

But that would bring back the discussion if such unpacked content belongs to the "image", so probably content store only would make more sense to track.

Some of that might impact how we present sizes in "docker image ls --tree" and "docker system df".

I guess for containers, it's less ambiguous, as they would always be tied to a specific snapshotter. We must still verify our code if we always use the container's property to reference the snapshotter though, as I recall early implementations tended to use the daemon's default as source of truth (thus not accounting for snapshotters to be differing per container)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to start favoring the content store as the source of truth for image storage and treat the snapshotter as a cached of the unpacked value, then it may be confusing to generically say this is how the image is "stored".

👍🏼 , pushed an updated revision to not have the field on image inspect. I still included the change to have the graph driver field be omitted because I assumed in the case the image is stored in containerd content store graph driver does not make sense.

as I recall early implementations tended to use the daemon's default as source of truth (thus not accounting for snapshotters to be differing per container)

Probably a few spots where we will find that assumption and need to refactor/redesign. First one that comes to mind is the image lease issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed an updated revision to not have the field on image inspect.

Yes, based on the discussion above, I think it makes sense to omit the field, and it keeps our options open for further discussion.

Probably a few spots where we will find that assumption and need to refactor/redesign. First one that comes to mind is the image lease issue.

Thanks! Yeah, I made a pass once in #45274, but it's possible that other locations are still there; I think this was the tracking-ticket I created for that;

@austinvazquez austinvazquez force-pushed the add-container-inspect-storage-driver branch from d14087d to ce4f594 Compare September 3, 2025 01:00
Comment on lines +148 to +149
// StorageDriver contains information about the container's storage driver.
StorageDriver storage.Driver `json:"StorageDriver,omitempty"`
Copy link
Contributor

@vvoland vvoland Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, this should not be tied to "driver" specifically.

I think a more general "Storage" struct would be better and more future proof.

Currently the only thing we need to store for container is the snapshot for the rootfs of the container.

package container

type Storage struct {
  RootFS  *RootFSStorage `json:",omitempty"`
}

Where RootFSStorage would be a poor mangoopher's union (with 1 variant at the moment):

type RootFSStorage struct {
  Snapshot   *RootFSStorageSnapshot `json:",omitempty"` 
}

type RootFSStorageSnapshot struct {
  SnapshotID string
  SnapshotterName string
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, that would also give us the possibility to introduce other storage types like:

type RootFSStorage struct {
  Snapshot   *RootFSStorageSnapshot `json:",omitempty"` 
  // Just an illustration, let's not add it yet:
  // Content      *RootFSStorageContent `json:",omitempty"` 

  // Perhaps something different that can hold a rootfs useable by the container
  // PigeonFS          *PigeonFS `json:",omitempty"` 
}

type RootFSStorageContent struct {
  Blobs []ocispec.Descriptor
}

type PigeonFS struct {
  // IDK, something that uses pigeons to provide rootfs
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could even move the graphdrivers driver data here using this approach:

type RootFSStorage struct {
  GraphDriver  *RootFSStorageGraphDriver `json:",omitempty"` 
  Snapshot      *RootFSStorageSnapshot `json:",omitempty"` 
}

Which in the current state of things, would mean that we could distinguish a container running under container vs graphdrivers by the existence of one of the variants.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(names subject to discussion of course 😅)

WDYT?

@thaJeztah @dmcgowan @austinvazquez

Copy link
Member

@thaJeztah thaJeztah Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, this should not be tied to "driver" specifically.

I think a more general "Storage" struct would be better and more future proof.

Yes, I think that makes sense.

Where RootFSStorage would be a poor mangopher's union (with 1 variant at the moment):

If we do this, perhaps we should add some discriminator in the struct to make it work well with Swagger and so that we can unmarshal to the right type;

type Storage {
	Type StorageType
	*StorageTypeFoo // some struct with information specific to "Foo" storage
	*StorageTypeBar // ...
	*StorageTypeBaz // ...
}

In swagger we can set that as discriminator, and when unmarshaling can use the field to decide what type to unmarshal the fields to (also accounting for cases where fields may overlap).

One thing we should still keep in mind is to limit the information where needed; i.e., if we don't need it for internal processing, then we should avoid exposing it through the API (at least; if we don't expect users to be tinkering with those things; #50857 (comment))

We could even move the graphdrivers driver data here using this approach

I don't think we should change anything for the graphdrivers; ultimately they will be removed, so we can keep the existing GraphDriver field (with the omitempty), and it will go away once graphdrivers are no longer a thing.

Of course, the downside would be that we need to continue carrying the GraphDriver field itself in the structs in the API, well, unless we "patch" the response for backward compatibility, but that may also be a bit ugly, because all existing API versions have the field.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do this, perhaps we should add some discriminator in the struct to make it work well with Swagger and so that we can unmarshal to the right type;

Yeah not sure about that! Maybe it would still be valuable to have multiple options possible, like with the snapshotter and content store:

type RootFSStorage struct {
  Snapshot   *RootFSStorageSnapshot `json:",omitempty"` 
  // Just an illustration, let's not add it yet:
  Content    *RootFSStorageContent `json:",omitempty"` 
}

type RootFSStorageContent struct {
  Config ocispec.Descriptor
  Layers []ocispec.Descriptor
}

Just thinking out loud though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@austinvazquez austinvazquez force-pushed the add-container-inspect-storage-driver branch from ce4f594 to 4c1bbf6 Compare September 22, 2025 20:17
@austinvazquez austinvazquez force-pushed the add-container-inspect-storage-driver branch 3 times, most recently from 0645a89 to 8ec7e31 Compare September 23, 2025 15:27
@austinvazquez austinvazquez changed the title Add container inspect storage driver Add container inspect storage field Sep 23, 2025
@austinvazquez
Copy link
Contributor Author

@vvoland, @thaJeztah, @dmcgowan if you folks can give this a look when you have the chance. I iterated on the generic storage type and decide to only include the snapshotter name for now for the rootfs storage when using containerd snapshotters.

Copy link
Contributor

@vvoland vvoland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one small doc nit

@austinvazquez austinvazquez force-pushed the add-container-inspect-storage-driver branch 2 times, most recently from 13ea429 to e1d4ad2 Compare September 26, 2025 18:34
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

found 2 minor issues, looks good otherwise

HostConfig:
$ref: "#/definitions/HostConfig"
GraphDriver:
x-nullable: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is missing in the main swagger.yaml (it's only in the v1.52.yaml 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow nice catch and also I forgot to add the Storage field in the container inspect response. Added in https://github.com/moby/moby/compare/e1d4ad209d70f3b34c49d177e9a6e182a6206905..efa077848f912b1c8febe579f345387e38008eb0

Comment on lines -82 to +85
_, err = c.ContainerInspect(ctx, containerID)
containerInspect, err := c.ContainerInspect(ctx, containerID)
assert.NilError(t, err, "Test container should still exist after daemon restart")
assert.Check(t, containerInspect.GraphDriver != nil, "GraphDriver should be set for graphdriver backend")
assert.Check(t, is.Equal(containerInspect.GraphDriver.Name, prevDriver), "Container graphdriver data should match")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a follow-up; we should check if we have a similar test for snapshotters;

  • start a daemon with snapshotter X
  • stop the daemon
  • start the daemon with snapshotter Y (e.g. "vis" or equivalent)
  • verify that we didn't try to switch the containers / images to a different snapshotter

(well; not sure if we support this scenario, but at least the stop/start as this test does)

This change defines the generic `Storage` type for use in container inspect responses when using containerd snapshotter backend.

Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
@austinvazquez austinvazquez force-pushed the add-container-inspect-storage-driver branch from e1d4ad2 to efa0778 Compare September 26, 2025 19:23
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thaJeztah thaJeztah merged commit 9b0c78e into moby:master Sep 26, 2025
327 of 334 checks passed
@austinvazquez austinvazquez deleted the add-container-inspect-storage-driver branch September 29, 2025 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api API area/daemon Core Engine impact/api kind/enhancement Enhancements are not bugs or new features but can improve usability or performance. module/api release-blocker PRs we want to block a release on

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants