Conversation
📝 WalkthroughWalkthroughPlumbs 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (2)
framework/docker/evstack/evmsingle/config.goframework/docker/evstack/evmsingle/node.go
| 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"} | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if UIDGID field is actually used when creating containers
rg -n "UIDGID" --type=go -C3Repository: 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 10Repository: 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 -60Repository: celestiaorg/tastora
Length of output: 272
🏁 Script executed:
#!/bin/bash
# Search for SetVolumeOwner more broadly
rg -n "SetVolumeOwner" --type=goRepository: 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 15Repository: 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.goRepository: celestiaorg/tastora
Length of output: 735
🏁 Script executed:
#!/bin/bash
# Search for where UidGid is used in node.go
rg -n "UidGid" --type=goRepository: 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.goRepository: 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 20Repository: 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.goRepository: 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.goRepository: 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.goRepository: 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 -20Repository: 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 2Repository: 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.
There was a problem hiding this comment.
🧹 Nitpick comments (2)
framework/docker/cosmos/chain_builder.go (1)
183-203: Consider copyinghomeDirinNewChainBuilderFromChain.When creating a builder from an existing chain, other configuration values are copied (e.g.,
Name,ChainID,Bin), buthomeDiris 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
homeDirinChainConfigand copy it:// After line 202, add: WithHomeDir(cfg.HomeDir)This requires adding a
HomeDirfield toChainConfigas 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 aDefaultHomeDir()helper for consistency.The hardcoded default
"/home/spamoor"works correctly, but other modules in this PR (reth, evmsingle, dataavailability, evstack) define aDefaultHomeDir()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
📒 Files selected for processing (15)
framework/docker/cosmos/chain_builder.goframework/docker/dataavailability/config.goframework/docker/dataavailability/network_builder.goframework/docker/dataavailability/node.goframework/docker/evstack/chain_builder.goframework/docker/evstack/config.goframework/docker/evstack/evmsingle/builder.goframework/docker/evstack/evmsingle/config.goframework/docker/evstack/evmsingle/node.goframework/docker/evstack/node.goframework/docker/evstack/reth/builder.goframework/docker/evstack/reth/config.goframework/docker/evstack/reth/node.goframework/docker/evstack/spamoor/builder.goframework/docker/evstack/spamoor/node.go
Overview
ref evstack/ev-node#3082
Summary by CodeRabbit