Skip to content

Implement rootless container introspection - #2617

Open
alexlarsson wants to merge 5 commits into
osbuild:mainfrom
alexlarsson:rootless-container-inspection
Open

Implement rootless container introspection#2617
alexlarsson wants to merge 5 commits into
osbuild:mainfrom
alexlarsson:rootless-container-inspection

Conversation

@alexlarsson

Copy link
Copy Markdown
Contributor

This makes container introspection (osinfo) work when run as non-root, by using unprivileged podman and looking in the per-user podman container storage.

Fixes #2568

This means something like image-builder manifest --bootc-default-fs ext4 --bootc-ref quay.io/fedora/fedora-bootc:44 qcow2 now works as a user.

NOTE; image-builder build, doesn't yet work as it needs some additional work to have osbuild look into the right container store.

This lets us read os-release files from other forms of sources.
This will let us later use a custom fs implementation to read from
other types of sources.
@alexlarsson
alexlarsson requested a review from a team as a code owner August 25, 2026 12:31
@supakeen
supakeen self-requested a review August 25, 2026 12:40
Comment thread pkg/container/client.go Outdated

dataHome := os.Getenv("XDG_DATA_HOME")
if dataHome == "" {
dataHome = filepath.Join(os.Getenv("HOME"), ".local", "share")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What if both are unset, then we end up with a relative path. Maybe that should blow up instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It seems very unlikely that HOME is not set. I just made it return the global store in that case.

Comment thread pkg/bootc/unsharefs.go
return entries, nil
}

func (fsys podmanUnshareFS) Open(name string) (fs.File, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think that we're supposed to be able to call Open() on a directory but that would fail with this implementation right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I fixed this

Comment thread pkg/bootc/unsharefs.go

// Ensure os.IsNotExist() works on the errors
func (fsys podmanUnshareFS) wrapErr(op, name string, err error) error {
if !fsys.exists(name) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't have a better idea but this triggers a second subprocess for each error case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The alternative is an "exists" subprocess for each operation, doesn't seem better...

supakeen
supakeen previously approved these changes Aug 26, 2026

@supakeen supakeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The previous PR was supposed to be an approval since I had only nitpicky small things but apparently I had hit the wrong checkbox.

supakeen
supakeen previously approved these changes Aug 26, 2026

@supakeen supakeen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for fixing my nits however unlikely they are to be triggered.

To make "podman mount" work in the rootless case we run it inside a
"podman unshare" wrapper. However, this means the mount is not visible
in the current namespace, all access to the mount must be done in
another process that is also inside a "podman unshare".

For this to work we switch Container.Root() to Container.RootFS(),
which in the rootless case is a new fs.FS implementation that accesses
the mount using standard tools (test/cat/stat/find) from the host inside
a "podman unshare".
If we're not uid 0, use the per-user container store instead of
the system global one.
@alexlarsson
alexlarsson force-pushed the rootless-container-inspection branch from 65d64f3 to 43288e2 Compare August 26, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rootless container inspection (HMS-11220)

2 participants