Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ Changelog

All notable changes to this project will be documented in this file.

## 4.80.1 - 2026-02-05

### Changed

- chroot: existing directories are now allowed. (@birdayz)

## 4.80.0 - 2026-02-04

### Added
Expand Down
17 changes: 12 additions & 5 deletions internal/cli/chroot_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
package cli

import (
"errors"
"fmt"
"io"
"io/fs"
Expand Down Expand Up @@ -45,10 +46,9 @@ func chroot(path string, passthroughFiles []string) error {
}

func setupChrootDir(chrootDir string, passthroughFiles []string) error {
// Make sure chroot directory does not exist
if _, err := os.Stat(chrootDir); err == nil {
return fmt.Errorf("chroot directory %s must not exist", chrootDir)
} else if !os.IsNotExist(err) {
// Allow the chroot directory to pre-exist (e.g. created by volume
// mounts). Only fail on unexpected stat errors.
if _, err := os.Stat(chrootDir); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("check directory: %w", err)
}

Expand Down Expand Up @@ -234,6 +234,13 @@ func makeReadOnly(root string) error {
if err != nil {
return err
}
return os.Chmod(filePath, info.Mode() & ^os.FileMode(0o222))
if err := os.Chmod(filePath, info.Mode() & ^os.FileMode(0o222)); err != nil {
// Ignore read-only filesystem errors from volume mounts.
if errors.Is(err, syscall.EROFS) {
return nil
}
return err
}
return nil
})
}
1 change: 0 additions & 1 deletion internal/cli/flags_redpanda.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ func applyLicenseFlag(c *cli.Context, conf *license.Config) {
var chrootFlag = &cli.StringFlag{
Name: "chroot",
Usage: "Chroot into the provided directory after parsing configuration. " +
"The directory must not exist and will be created. " +
"Common /etc/ files are copied to the chroot directory, and the directory is made read-only. " +
"This flag is only supported on Linux.",
}
Expand Down
6 changes: 6 additions & 0 deletions resources/docker/cloud.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ COPY --from=build /etc/passwd /etc/passwd
COPY --from=build /tmp/redpanda-connect /redpanda-connect
COPY config/docker.yaml /connect.yaml

# Pre-create the chroot directory so that volume mounts placed inside it
# (e.g. ConfigMaps at /tmp/chroot/...) don't cause kubelet to create it
# as root-owned, which would prevent the connect user from populating the
# rest of the chroot structure at runtime.
RUN mkdir -p /tmp/chroot && chown 10001:10001 /tmp/chroot

USER connect

EXPOSE 4195
Expand Down