Skip to content

Conversation

@mikusaq
Copy link
Contributor

@mikusaq mikusaq commented Jan 30, 2026

  • Add Docker environment check
    • check if directories can be created and accessed in Docker container by Packager
    • check if volume directories can be accessed in Docker container by Packager
  • Fix for systems with SELinux
  • Refactor
    • better error handling
    • dockerStop and DockerRm usage moved to one place
    • simplification around os.MkDirAll usage
    • remove unnecessary sleep before removing containers

Summary by CodeRabbit

  • New Features

    • Added Docker environment validation before determining platform.
  • Bug Fixes

    • Improved sysroot path error handling and safer filesystem operations.
    • More reliable container cleanup via centralized undo handlers and logged errors.
  • Refactor

    • Platform detection now expects a prepared container; container lifecycle simplified.
    • Consolidated sysroot creation/permissions and introduced a dedicated container sysroot path.
  • Tests

    • Updated tests to handle sysroot path errors and new APIs.

✏️ Tip: You can customize this high-level summary in your review settings.

@mikusaq mikusaq requested a review from koudis January 30, 2026 12:31
@mikusaq mikusaq self-assigned this Jan 30, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Centralizes Docker environment validation and shifts platform-string discovery to rely on an already-running container; introduces undo-handler based container cleanup, adds a container sysroot mount constant, and changes sysroot APIs to return errors and use the container mount path.

Changes

Cohort / File(s) Summary
Mode Entry Points
cmd/bap-builder/AppMode.go, cmd/bap-builder/PackageMode.go, cmd/bap-builder/SysrootMode.go
Replaced direct determinePlatformString calls with checkDockerEnvironmentAndDeterminePlatformString to perform Docker env checks and obtain PlatformString (plus undo handler) before continuing mode-specific flows.
Docker Environment Validation & Helpers
cmd/bap-builder/PackageMode.go
Added prepareDockerEnvironmentCheck, checkDockerEnvironment, and checkDockerEnvironmentAndDeterminePlatformString to create test sysroot, run a container, prepare SSH creds, validate permissions/paths, and return PlatformString + undo handler. Introduced time-based test dir naming.
Platform Metadata
internal/bacpack_package/PlatformString.go
Removed container lifecycle management from determinePlatformString; it now expects an already-running container and extracts distro/release and architecture without starting/stopping containers. Removed process/time imports.
Docker Run & Undo Handling
internal/docker/DockerRun.go
Added GetUndoHandler() returning a cleanup function that stops and removes the container (with logged errors). Volume mappings now append :Z for SELinux relabeling.
Build Orchestration
internal/build/Build.go
Replaced manual delayed signal-based stop/remove logic with dockerRun.GetUndoHandler() (deferred). Use constants.ContainerSysrootPath for mount and set BuildSystem.PrefixPath accordingly. Removed stopAndRemoveContainer.
Constants
internal/constants/Constants.go
Added exported ContainerSysrootPath = "/sysroot".
Sysroot Management & Tests
internal/sysroot/Sysroot.go, internal/sysroot/default_test.go
Changed GetSysrootPath()(string, error) and CreateSysrootDir()error; added GetBaseSysrootPath() and CreateBaseSysrootDir(). Improved error handling/permissions and updated tests to check returned errors and use returned paths.
Misc / Imports & Tests
internal/bacpack_package/PlatformString.go (imports), internal/build/Build.go (removed helper)
Removed unused imports and deleted the old container stop/remove helper; adjusted imports to match new cleanup pattern.

Sequence Diagram(s)

sequenceDiagram
    participant Operator as Operator
    participant Mode as Mode (App/Package/Sysroot)
    participant Docker as DockerRun
    participant Sysroot as SysrootService
    participant Platform as PlatformString

    Operator->>Mode: start build
    Mode->>Docker: checkDockerEnvironmentAndDeterminePlatformString(image, port)
    Docker->>Sysroot: CreateBaseSysrootDir() / prepare test sysroot
    Sysroot-->>Docker: base sysroot path
    Docker->>Docker: run container, mount sysroot -> rgba(255,165,0,0.5)
    Docker->>Docker: create SSH credentials
    Docker->>Docker: checkDockerEnvironment (permissions, container paths)
    Docker->>Platform: determinePlatformString(on running container)
    Platform-->>Docker: PlatformString
    Docker-->>Mode: return PlatformString + undo handler
    Mode->>Mode: proceed with build using PlatformString
    Mode->>Docker: defer undo handler (stop & remove container)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • koudis
  • Melky-Phoe

Poem

🐇 I hopped into a mounted tree,
Made a sysroot, tidy as can be,
An undo handler clears my trail,
Platform strings return without fail,
Hooray — the rabbit’s build is free!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add Docker environment check' directly and accurately summarizes the main purpose of this pull request, which is to add Docker environment validation functionality.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BAF-1299/check-docker-permissions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mikusaq
Copy link
Contributor Author

mikusaq commented Jan 30, 2026

Works as expected on Ubuntu 24.04 (without SELinux) and Fedora 43 (with SELinux). All tests have passed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/sysroot/default_test.go (1)

111-123: ⚠️ Potential issue | 🟡 Minor

Assert CreateSysrootDir() errors in the test.

CreateSysrootDir now returns an error; the test should fail explicitly if it can’t create the directory.

✅ Suggested test fix
-	defaultSysroot.CreateSysrootDir()
+	if err := defaultSysroot.CreateSysrootDir(); err != nil {
+		t.Fatalf("CreateSysrootDir failed - %s", err)
+	}
🤖 Fix all issues with AI agents
In `@cmd/bap-builder/PackageMode.go`:
- Around line 413-415: The shell command string in ssh.ShellEvaluator (variable
shellEvaluator, field Commands) is missing spaces before the path for the `test
-r` and `test -w` checks; update the command that builds from testDir to insert
a space after `test -r` and `test -w` (e.g., `"mkdir " + testDir + " && test -r
" + testDir + " && test -w " + testDir + " && rmdir " + testDir"`) so the tests
run with valid shell syntax.
- Around line 405-407: The docstring for checkDockerEnvironment in
PackageMode.go is incorrect (it describes downloading/cloning); update the
comment above the checkDockerEnvironment function to accurately state that it
validates Docker environment permissions and availability (e.g., checks Docker
daemon connectivity, user permissions, and required capabilities) and remove any
copy-pasted references to downloading packages or updating submodules so the
comment matches the function's actual behavior and checks.
- Around line 440-444: Remove the redundant assignment to
defaultDocker.ImageName after creating the Docker instance: the call to
prerequisites.CreateAndInitialize[docker.Docker](dockerImageName, dockerPort)
already sets ImageName via docker.Docker.FillDynamic, so delete the line that
assigns defaultDocker.ImageName = dockerImageName; keep the CreateAndInitialize
call and subsequent logic unchanged.

In `@internal/build/Build.go`:
- Around line 159-166: CreateSysrootDir()'s error is being ignored; update the
block that checks build.sysroot to capture and return any error from
build.sysroot.CreateSysrootDir() before calling GetSysrootPath and SetVolume. In
the code around Build.sysroot, call CreateSysrootDir(), check its error (e.g.,
if err := build.sysroot.CreateSysrootDir(); err != nil), and return that error
(or wrap it with context) so subsequent calls to build.sysroot.GetSysrootPath()
and build.Docker.SetVolume() don't run on a failed setup.

In `@internal/sysroot/Sysroot.go`:
- Around line 18-20: The constant sysrootDirPermissions is set to world‑writable
0777 which is insecure; change sysrootDirPermissions to a safer default such as
0755 (or 0775 if group write is needed) and add a comment noting the choice, and
optionally make permissions configurable (e.g., via a setter or config value
used by the code that creates the directory) so callers can override when
broader access is required; update any code that relies on sysrootDirPermissions
to read the configurable value instead of the hardcoded 0777.
- Around line 175-188: The comment for CreateSysrootDir is outdated (it says it
panics) even though the function now returns an error; update the function
comment to accurately state that CreateSysrootDir creates the sysroot directory
and returns an error on failure instead of panicking, mentioning the Sysroot
receiver and that it uses GetSysrootPath and os.MkdirAll to create the directory
and propagate errors.
- Around line 138-158: The comment for CreateBaseSysrootDir is outdated (it
claims a panic occurs) — update the function doc to accurately state that
CreateBaseSysrootDir returns an error on failure instead of panicking; mention
that it uses GetBaseSysrootPath and os.MkdirAll and that callers should handle
the returned error.
🧹 Nitpick comments (2)
internal/docker/DockerRun.go (1)

42-58: Avoid fixed sleep and surface cleanup failures.

Run() is synchronous, so the fixed 200ms delay is likely unnecessary. Also, returning the first stop/remove error would let non-deferred callers react to cleanup failures.

♻️ Suggested tweak
 func (args *DockerRun) GetUndoHandler() func() error {
 	return func() error {
-		// Waiting for docker run command to get container id
-		time.Sleep(200 * time.Millisecond)
+		if args.containerId == "" {
+			return nil
+		}
 		dockerStop := (*DockerStop)(args)
 		dockerRm := (*DockerRm)(args)

 		logger := log.GetLogger()
-		err := dockerStop.Stop()
-		if err != nil {
+		if err := dockerStop.Stop(); err != nil {
 			logger.Error("Can't stop container - %s", err)
+			return err
 		}
-		err = dockerRm.RemoveContainer()
-		if err != nil {
+		if err := dockerRm.RemoveContainer(); err != nil {
 			logger.Error("Can't remove container - %s", err)
+			return err
 		}
 		return nil
 	}
 }
internal/sysroot/Sysroot.go (1)

194-199: Consider logging when GetSysrootPath fails.

Returning “empty” on path resolution errors can hide real issues; a warning log would make this easier to debug.

🔎 Optional logging
 	sysrootPath, err := sysroot.GetSysrootPath()
 	if err != nil {
+		log.GetLogger().Warn("Cannot resolve sysroot path: %s", err)
 		return true
 	}

@mikusaq mikusaq force-pushed the BAF-1299/check-docker-permissions branch from 7565df8 to d6d2e59 Compare January 30, 2026 13:07
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@cmd/bap-builder/PackageMode.go`:
- Around line 456-492: The deferred container cleanup handler is obtained before
dockerRun.Run and will run even if Run fails, causing spurious "container not
found" errors; move the call to dockerRun.GetUndoHandler() and the defer
removeHandler() to immediately after dockerRun.Run() returns successfully (i.e.,
only call GetUndoHandler() and defer it when dockerRun.Run() returns nil) inside
checkDockerEnvironmentAndDeterminePlatformString so cleanup is registered only
for actually created containers (keep references to dockerRun, GetUndoHandler,
removeHandler and ensure error handling still returns on Run failure).

In `@internal/docker/DockerRun.go`:
- Around line 42-58: GetUndoHandler currently always sleeps and runs Stop/Remove
even if the DockerRun's containerId is empty; add an early guard in
DockerRun.GetUndoHandler that checks the receiver's containerId (e.g.,
args.containerId or the appropriate field on DockerRun) and if it's empty return
a no-op func immediately to avoid the 200ms sleep and calling
DockerStop.Stop/DockerRm.RemoveContainer with an empty id; keep existing error
logging for non-empty cases and do not call Stop/Remove when containerId is
blank.
🧹 Nitpick comments (2)
cmd/bap-builder/PackageMode.go (1)

405-429: Include underlying SSH error in diagnostics.

Both failure branches discard err, which makes triage harder. Consider logging and wrapping the underlying error.

🧩 Suggested tweak
 	err := shellEvaluator.RunOverSSH(credentials)
 	if err != nil {
-		logger.ErrorIndent("Cannot create directories, or read or write to them inside Docker container")
-		return fmt.Errorf("invalid Docker environment")
+		logger.ErrorIndent("Cannot create directories, or read or write to them inside Docker container - %s", err)
+		return fmt.Errorf("invalid Docker environment: %w", err)
 	}
@@
 	err = shellEvaluator.RunOverSSH(credentials)
 	if err != nil {
-		logger.ErrorIndent("Cannot read volume directory inside Docker container")
-		return fmt.Errorf("invalid Docker environment")
+		logger.ErrorIndent("Cannot read volume directory inside Docker container - %s", err)
+		return fmt.Errorf("invalid Docker environment: %w", err)
 	}
internal/sysroot/Sysroot.go (1)

194-200: Log GetSysrootPath failures for visibility.

Right now failures are silent and return true; a warning helps diagnose path/permission issues.

🧩 Suggested tweak
 	sysrootPath, err := sysroot.GetSysrootPath()
 	if err != nil {
+		log.GetLogger().Warn("Cannot resolve sysroot path: %s", err)
 		return true
 	}

@mikusaq mikusaq force-pushed the BAF-1299/check-docker-permissions branch from d6d2e59 to bc131ce Compare January 30, 2026 13:19
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/build/Build.go (1)

205-214: ⚠️ Potential issue | 🟡 Minor

Defer cleanup only after a successful container start.
If dockerRun.Run() fails, the deferred cleanup may attempt to stop/remove a non‑existent container and emit noisy errors.

🧹 Proposed fix
 	dockerRun := (*docker.DockerRun)(build.Docker)
-	removeHandler := dockerRun.GetUndoHandler()
-	defer removeHandler()
-
 	logger.InfoIndent("Starting docker container")
 
 	err = dockerRun.Run()
 	if err != nil {
 		return err, false
 	}
+	removeHandler := dockerRun.GetUndoHandler()
+	defer removeHandler()
🤖 Fix all issues with AI agents
In `@cmd/bap-builder/PackageMode.go`:
- Around line 436-453: The function prepareDockerEnvironmentCheck calls
defaultDocker.SetVolume(sysrootPath, constants.ContainerSysrootPath) but ignores
any error; validate and propagate SetVolume's error so a failed volume mount
fails the environment check. Update prepareDockerEnvironmentCheck to capture the
return from defaultDocker.SetVolume, return that error (or wrap it with context)
before returning defaultDocker, ensuring callers receive the failure from
SetVolume.
🧹 Nitpick comments (1)
internal/sysroot/Sysroot.go (1)

194-198: Log GetSysrootPath failures before treating sysroot as empty.
Silent fallback makes debugging permission/FS issues harder.

🔍 Proposed tweak
 	sysrootPath, err := sysroot.GetSysrootPath()
 	if err != nil {
+		log.GetLogger().Warn("Cannot resolve sysroot path: %s", err)
 		return true
 	}

@mikusaq mikusaq force-pushed the BAF-1299/check-docker-permissions branch from bc131ce to 8243ac3 Compare January 30, 2026 13:30
@mikusaq mikusaq force-pushed the BAF-1299/check-docker-permissions branch from 8243ac3 to e22de16 Compare January 30, 2026 13:33
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.

2 participants