Skip to content

chore: updating home dirs to not use root#185

Open
chatton wants to merge 2 commits intomainfrom
cian/update-root-user
Open

chore: updating home dirs to not use root#185
chatton wants to merge 2 commits intomainfrom
cian/update-root-user

Conversation

@chatton
Copy link
Collaborator

@chatton chatton commented Mar 18, 2026

Overview

ref evstack/ev-node#3082

Summary by CodeRabbit

  • New Features
    • Add fluent option to override container home directory for chains, networks, and node builders.
  • Chores
    • Standardized default home directories for several components.
    • Default container images now include UID:GID to improve runtime ownership consistency.

@chatton chatton requested a review from tty47 as a code owner March 18, 2026 08:44
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

Plumbs customizable container home directories across multiple docker builders/nodes and adds DefaultHomeDir helpers; also updates evmsingle default image to include UIDGID "10001:10001". Several NewNode signatures and builder APIs gained homeDir wiring and WithHomeDir methods.

Changes

Cohort / File(s) Summary
evstack / evmsingle
framework/docker/evstack/evmsingle/config.go, framework/docker/evstack/evmsingle/builder.go, framework/docker/evstack/evmsingle/node.go
Added HomeDir field on Config/Builder, WithHomeDir on builder, DefaultHomeDir() helper; DefaultImage now includes UIDGID: "10001:10001". Node creation now receives and uses configured HomeDir.
evstack / reth & spamoor
framework/docker/evstack/reth/config.go, framework/docker/evstack/reth/builder.go, framework/docker/evstack/reth/node.go, framework/docker/evstack/spamoor/builder.go, framework/docker/evstack/spamoor/node.go
Added HomeDir/homeDir fields and WithHomeDir builders; nodes now accept/plumb homeDir (defaulted via DefaultHomeDir) instead of hardcoded paths.
evstack / chain builders
framework/docker/evstack/chain_builder.go, framework/docker/evstack/evmsingle/.../builder.go
ChainBuilder gains homeDir/HomeDir and WithHomeDir; chain node creation now passes builder homeDir through to NewNode.
evstack / package defaults
framework/docker/evstack/config.go
Added package-level DefaultHomeDir() helper returning the evstack default path.
dataavailability
framework/docker/dataavailability/config.go, framework/docker/dataavailability/network_builder.go, framework/docker/dataavailability/node.go
Added DefaultHomeDir() and WithHomeDir on NetworkBuilder; NewNode signature updated to accept homeDir and node construction now uses provided or defaulted homeDir.
cosmos
framework/docker/cosmos/chain_builder.go
ChainBuilder gained homeDir field and WithHomeDir; node creation now honors the override when present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • tty47
  • mojtaba-esk

Poem

🐰 In burrows of code I hop and sing,

Paths now bend where HomeDirs spring,
Builders pass the comfy nest,
Images gain a UIDGID guest,
Hop, deploy — containers rest. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: making home directories configurable across all components to remove root usage.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cian/update-root-user
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Copy link
Contributor

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@framework/docker/evstack/evmsingle/config.go`:
- Around line 27-29: DefaultImage sets UIDGID to "10001:10001" but the container
runtime user isn't set, causing permission mismatches; update CreateContainer to
set container.Config.User = image.UIDGID (where image is the container.Image
passed into CreateContainer) so the runtime user matches the volume owner
configured by SetOwner(), ensuring DefaultImage(), UIDGID, CreateContainer,
container.Config and SetOwner are consistent; alternatively document in
DefaultImage that the upstream image already runs as UID 10001 if you choose not
to set User programmatically.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 37c9b244-832b-4869-a619-7ec6eb759c2e

📥 Commits

Reviewing files that changed from the base of the PR and between 227152d and 8856403.

📒 Files selected for processing (2)
  • framework/docker/evstack/evmsingle/config.go
  • framework/docker/evstack/evmsingle/node.go

Comment on lines 27 to 29
func DefaultImage() container.Image {
// Default ev-node tag pinned for reproducibility
return container.Image{Repository: "ghcr.io/evstack/ev-node-evm", Version: "v1.0.0-rc.4"}
return container.Image{Repository: "ghcr.io/evstack/ev-node-evm", Version: "v1.0.0-rc.4", UIDGID: "10001:10001"}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if UIDGID field is actually used when creating containers
rg -n "UIDGID" --type=go -C3

Repository: celestiaorg/tastora

Length of output: 13996


🏁 Script executed:

#!/bin/bash
# Check CreateContainer implementation to see if user is set
ast-grep --pattern $'func ($_ $_) CreateContainer($$$) $_ {
  $$$
}'

Repository: celestiaorg/tastora

Length of output: 6584


🏁 Script executed:

#!/bin/bash
# Find SetVolumeOwner implementation
rg -n "SetVolumeOwner" --type=go -A 10

Repository: celestiaorg/tastora

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check if User field is set anywhere in container creation
rg -n "\.User\s*=" --type=go framework/docker/container/

Repository: celestiaorg/tastora

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check container.Config and container.HostConfig struct usage more thoroughly
rg -n "container\.Config|container\.HostConfig" --type=go -A 3 framework/docker/container/lifecycle.go | head -60

Repository: celestiaorg/tastora

Length of output: 272


🏁 Script executed:

#!/bin/bash
# Search for SetVolumeOwner more broadly
rg -n "SetVolumeOwner" --type=go

Repository: celestiaorg/tastora

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check what SetVolumeOwner does - search for the full implementation
rg -n "func.*SetVolumeOwner" --type=go -A 15

Repository: celestiaorg/tastora

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Look at the complete container.Config struct creation in lifecycle.go
sed -n '94,122p' framework/docker/container/lifecycle.go

Repository: celestiaorg/tastora

Length of output: 735


🏁 Script executed:

#!/bin/bash
# Search for where UidGid is used in node.go
rg -n "UidGid" --type=go

Repository: celestiaorg/tastora

Length of output: 265


🏁 Script executed:

#!/bin/bash
# Get the full context around line 183 in node.go
sed -n '175,195p' framework/docker/container/node.go

Repository: celestiaorg/tastora

Length of output: 677


🏁 Script executed:

#!/bin/bash
# Look at the SetOwner implementation to see what it does
rg -n "func.*SetOwner" --type=go -A 20

Repository: celestiaorg/tastora

Length of output: 1485


🏁 Script executed:

#!/bin/bash
# Check the volume/owner.go file to understand what SetOwner does
cat -n framework/docker/volume/owner.go

Repository: celestiaorg/tastora

Length of output: 3613


🏁 Script executed:

#!/bin/bash
# Search for how other projects set the User field in container config
rg -n "User:" --type=go framework/docker/

Repository: celestiaorg/tastora

Length of output: 665


🏁 Script executed:

#!/bin/bash
# Check job.go to understand when User field is set
sed -n '170,185p' framework/docker/container/job.go

Repository: celestiaorg/tastora

Length of output: 470


🏁 Script executed:

#!/bin/bash
# Check the Job struct and its CreateContainer method
rg -n "type Job struct" --type=go -A 10 framework/docker/container/job.go

Repository: celestiaorg/tastora

Length of output: 283


🏁 Script executed:

#!/bin/bash
# Verify if job.go CreateContainer is used for the main application or for utilities
rg -n "job\.CreateContainer\|\.CreateJobContainer" --type=go | head -20

Repository: celestiaorg/tastora

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Check if there's any documentation or comments about the upstream image default user
rg -n "ev-node-evm\|ev-node" --type=go framework/docker/evstack/ -B 2 -A 2

Repository: celestiaorg/tastora

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Verify: in lifecycle.go, the container.Config does NOT have User field set anywhere
# Let me get the full CreateContainer function
cat -n framework/docker/container/lifecycle.go | sed -n '45,129p'

Repository: celestiaorg/tastora

Length of output: 2537


The container does not actually run as UID 10001:10001 - the User field is missing from the container configuration.

The UIDGID: "10001:10001" only configures volume ownership (via SetOwner()), not the container's runtime user. The CreateContainer method in framework/docker/container/lifecycle.go does not set the User field in container.Config, so the container runs as whatever default user the upstream image specifies.

This creates a critical mismatch: if the image doesn't default to UID 10001, the volume (owned by 10001:10001) will have permission issues when the container writes files as a different user. Additionally, if the image defaults to root, you'd be running as root unnecessarily.

Either set User: image.UIDGID in the container.Config (lines 96-104 of lifecycle.go), or document that the upstream image ghcr.io/evstack/ev-node-evm:v1.0.0-rc.4 is already configured to run as UID 10001 by default.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/docker/evstack/evmsingle/config.go` around lines 27 - 29,
DefaultImage sets UIDGID to "10001:10001" but the container runtime user isn't
set, causing permission mismatches; update CreateContainer to set
container.Config.User = image.UIDGID (where image is the container.Image passed
into CreateContainer) so the runtime user matches the volume owner configured by
SetOwner(), ensuring DefaultImage(), UIDGID, CreateContainer, container.Config
and SetOwner are consistent; alternatively document in DefaultImage that the
upstream image already runs as UID 10001 if you choose not to set User
programmatically.

Copy link
Contributor

@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.

🧹 Nitpick comments (2)
framework/docker/cosmos/chain_builder.go (1)

183-203: Consider copying homeDir in NewChainBuilderFromChain.

When creating a builder from an existing chain, other configuration values are copied (e.g., Name, ChainID, Bin), but homeDir is not included. If the original chain used a custom home directory, the new builder will use the default instead.

This may be intentional, but worth verifying whether consistency is desired here.

💡 Suggested addition if homeDir should be preserved

You would need to store homeDir in ChainConfig and copy it:

// After line 202, add:
WithHomeDir(cfg.HomeDir)

This requires adding a HomeDir field to ChainConfig as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/docker/cosmos/chain_builder.go` around lines 183 - 203,
NewChainBuilderFromChain currently copies many fields from Chain.Config but
omits homeDir; add a HomeDir string field to the ChainConfig struct and update
NewChainBuilderFromChain to call WithHomeDir(cfg.HomeDir) on the ChainBuilder so
the builder preserves custom home directories; ensure the ChainBuilder has a
WithHomeDir method (or add one) to accept and store the HomeDir value.
framework/docker/evstack/spamoor/node.go (1)

49-52: Consider adding a DefaultHomeDir() helper for consistency.

The hardcoded default "/home/spamoor" works correctly, but other modules in this PR (reth, evmsingle, dataavailability, evstack) define a DefaultHomeDir() function. Adding one here would improve maintainability and consistency.

♻️ Suggested refactor

Add to this file or a separate config.go:

// DefaultHomeDir returns the default home directory for spamoor containers.
func DefaultHomeDir() string {
    return "/home/spamoor"
}

Then update the defaulting logic:

 func newNode(ctx context.Context, cfg Config, testName string, index int, name string, homeDir string) (*Node, error) {
     if homeDir == "" {
-        homeDir = "/home/spamoor"
+        homeDir = DefaultHomeDir()
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/docker/evstack/spamoor/node.go` around lines 49 - 52, Add a
DefaultHomeDir() helper that returns "/home/spamoor" (e.g., in this file or a
new config.go) and update newNode to call DefaultHomeDir() instead of hardcoding
the string; specifically, add the function DefaultHomeDir() and change the
defaulting branch in newNode (the homeDir == "" check) to set homeDir =
DefaultHomeDir() so the module follows the same pattern as
reth/evmsingle/dataavailability/evstack.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@framework/docker/cosmos/chain_builder.go`:
- Around line 183-203: NewChainBuilderFromChain currently copies many fields
from Chain.Config but omits homeDir; add a HomeDir string field to the
ChainConfig struct and update NewChainBuilderFromChain to call
WithHomeDir(cfg.HomeDir) on the ChainBuilder so the builder preserves custom
home directories; ensure the ChainBuilder has a WithHomeDir method (or add one)
to accept and store the HomeDir value.

In `@framework/docker/evstack/spamoor/node.go`:
- Around line 49-52: Add a DefaultHomeDir() helper that returns "/home/spamoor"
(e.g., in this file or a new config.go) and update newNode to call
DefaultHomeDir() instead of hardcoding the string; specifically, add the
function DefaultHomeDir() and change the defaulting branch in newNode (the
homeDir == "" check) to set homeDir = DefaultHomeDir() so the module follows the
same pattern as reth/evmsingle/dataavailability/evstack.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e153db36-0a1e-43f5-bc5a-089a252392ca

📥 Commits

Reviewing files that changed from the base of the PR and between 8856403 and 5531019.

📒 Files selected for processing (15)
  • framework/docker/cosmos/chain_builder.go
  • framework/docker/dataavailability/config.go
  • framework/docker/dataavailability/network_builder.go
  • framework/docker/dataavailability/node.go
  • framework/docker/evstack/chain_builder.go
  • framework/docker/evstack/config.go
  • framework/docker/evstack/evmsingle/builder.go
  • framework/docker/evstack/evmsingle/config.go
  • framework/docker/evstack/evmsingle/node.go
  • framework/docker/evstack/node.go
  • framework/docker/evstack/reth/builder.go
  • framework/docker/evstack/reth/config.go
  • framework/docker/evstack/reth/node.go
  • framework/docker/evstack/spamoor/builder.go
  • framework/docker/evstack/spamoor/node.go

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.

1 participant