Skip to content

Conversation

@NaysKutzu
Copy link
Contributor

@NaysKutzu NaysKutzu commented Nov 29, 2025

Yes, tested in FeatherWings by around 400 hosts migrating from pterodactyl wings

Summary by CodeRabbit

  • Bug Fixes

    • Added retry when requested network subnets conflict or are invalid, avoiding hard failures.
    • Runtime network settings now reflect Docker-assigned subnets and gateways (IPv6 prioritized, then IPv4).
  • Refactor

    • Network creation/resync flow updated to validate, re-inspect and log actual Docker network configuration rather than relying on a post-create fallback.

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

@NaysKutzu NaysKutzu requested a review from a team as a code owner November 29, 2025 21:41
@coderabbitai
Copy link

coderabbitai bot commented Nov 29, 2025

Walkthrough

After creating a Docker network, the code now re-inspects the network to capture Docker-assigned IPAM results, propagates actual IPv6/IPv4 Subnet and Gateway values into runtime interfaces, and retries network creation without explicit IPAM when Docker reports pool-overlap/invalid-pool errors.

Changes

Cohort / File(s) Change Summary
Docker network logic
environment/docker.go
Added strings import. createDockerNetwork builds IPAMConfig entries for configured IPv4 and optional IPv6 subnets/gateways and supplies them during create; on create failure detecting pool-overlap/invalid-pool it logs a warning and retries creation without explicit IPAM (letting Docker auto-assign subnets), logging success on retry. ConfigureDocker now re-inspects the created network to read actual IPAM Subnet/Gateway values and copies them into IPv6/IPv4 interface configs (IPv6 first, then IPv4) and sets the overall Interface to the IPv4 gateway when present. Removed previous unconditional post-create fallback that set Interface from configured V4.Gateway. Errors on inspect are wrapped and returned.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Verify string-matching used to detect pool-overlap/invalid-pool covers Docker error variants and i18n/localization.
  • Review IPAMConfig construction for correct ordering, nil handling, and gateway/subnet mapping for IPv4 vs IPv6.
  • Confirm retry branch only triggers for intended error cases and preserves original error context on final failure.
  • Validate re-inspect logic correctly handles Docker-assigned IPAM entries, missing fields, and that Interface selection (IPv4 gateway preference) is correct and documented in code paths.

Poem

🐰 I nudge the nets with twitchy paws,

Pools collide — I try once more.
Docker sings its real address laws,
I copy gates and settle the shore.
Hop! The network hums, I bound and snore.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: fixing subnet configuration and handling the pool overlap error through retry logic and IPAM propagation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@NaysKutzu NaysKutzu changed the title Fix subnet Fix subnets and the common error: Pool overlaping Nov 29, 2025
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96a1251 and fb04e57.

📒 Files selected for processing (1)
  • environment/docker.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
environment/docker.go (2)
config/config.go (1)
  • Get (421-429)
server/filesystem/errors.go (1)
  • Error (25-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.25.1, linux, amd64)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.24.7, linux, amd64)
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
environment/docker.go (3)

52-57: LGTM: Re-inspecting the network after creation ensures configuration accuracy.

This correctly captures the actual IPAM settings Docker assigned, especially important when the retry path uses auto-assigned subnets.


100-115: LGTM: IPAM configuration building is correct.

The logic properly builds IPAM configs from the configured subnets, handling IPv4 and optional IPv6 appropriately.


136-158: Based on my research, I can now provide you with the rewritten review comment:


Error message substring matching is a pragmatic and stable approach; no better alternative exists in the Docker Go client.

The error messages "Pool overlaps" and "invalid pool request" originate from Docker's libnetwork IPAM error constants and have remained stable across Docker versions 20–27. The Go docker SDK does not expose a typed error for pool-overlap conditions, so string matching on err.Error() is the documented and recommended pattern (see Docker Go client examples and moby/moby issue discussions). The substring-based approach (strings.Contains()) is actually more robust than exact matching, as it tolerates minor wording variations in the daemon message. The implementation follows best practices for this scenario.

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: 0

🧹 Nitpick comments (1)
environment/docker.go (1)

141-143: String-based error detection is fragile.

Docker error messages may vary across versions or locales. Consider using case-insensitive matching for more robustness.

 	// Check if the error is a pool overlap issue
 	errStr := err.Error()
-	if strings.Contains(errStr, "Pool overlaps") || strings.Contains(errStr, "invalid pool request") {
+	errLower := strings.ToLower(errStr)
+	if strings.Contains(errLower, "pool overlaps") || strings.Contains(errLower, "invalid pool request") {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb04e57 and a78ca72.

📒 Files selected for processing (1)
  • environment/docker.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
environment/docker.go (1)
config/config.go (1)
  • Get (421-429)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.24.7, linux, amd64)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.25.1, linux, amd64)
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
environment/docker.go (3)

52-57: LGTM!

Re-inspecting the network after creation is the correct approach to obtain Docker-assigned values, especially when the retry logic falls back to auto-assignment.


74-93: Previous review concern addressed.

The iteration-based approach correctly handles Docker's unordered IPAM config by detecting address family via colon presence. This is robust since IPv6 addresses always contain colons while IPv4 addresses never do.


98-164: Retry logic for subnet conflicts looks good.

The approach of falling back to Docker auto-assignment when configured subnets conflict is a practical solution for the migration scenario described in the PR. The error handling is appropriate, and the flow is clear.

@NaysKutzu
Copy link
Contributor Author

Actionable comments posted: 0

🧹 Nitpick comments (1)

environment/docker.go (1)> 141-143: String-based error detection is fragile.

Docker error messages may vary across versions or locales. Consider using case-insensitive matching for more robustness.

 	// Check if the error is a pool overlap issue
 	errStr := err.Error()
-	if strings.Contains(errStr, "Pool overlaps") || strings.Contains(errStr, "invalid pool request") {
+	errLower := strings.ToLower(errStr)
+	if strings.Contains(errLower, "pool overlaps") || strings.Contains(errLower, "invalid pool request") {

📜 Review details

No, not true those kind of errors are the same :/

…host, overlay, weavemesh) that don't use standard IPAM configs.
@NaysKutzu NaysKutzu requested a review from QuintenQVD0 December 1, 2025 12:43
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: 0

🧹 Nitpick comments (1)
environment/docker.go (1)

145-146: Error string matching is case-sensitive and fragile.

Matching exact error-string fragments can break if Docker changes message wording across versions or locales. While I see from PR comments that you disagree, consider at minimum using case-insensitive matching for resilience:

-		errStr := err.Error()
-		if strings.Contains(errStr, "Pool overlaps") || strings.Contains(errStr, "invalid pool request") {
+		errStr := strings.ToLower(err.Error())
+		if strings.Contains(errStr, "pool overlaps") || strings.Contains(errStr, "invalid pool request") {

Alternatively, Docker client errors often implement specific types or error codes that could be checked instead of string matching.

Docker SDK Go network create error types for pool overlap
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a78ca72 and d8f714d.

📒 Files selected for processing (1)
  • environment/docker.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
environment/docker.go (1)
config/config.go (1)
  • Get (421-429)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (go)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.24.7, linux, amd64)
  • GitHub Check: Build and Test (ubuntu-22.04, 1.25.1, linux, amd64)
🔇 Additional comments (4)
environment/docker.go (4)

52-57: LGTM!

Re-inspecting the network after creation ensures the configuration reflects actual Docker-assigned values. Error handling with context is properly implemented.


74-96: LGTM - correctly handles non-deterministic IPAM config ordering.

The iteration approach with colon-based IPv6 detection properly addresses the previous review concern about Docker not guaranteeing IPAM config order. The driver exclusion list is consistent with the switch statement above.


109-121: LGTM!

IPAM config building correctly includes only non-empty subnets, with IPv6 config added only when IPv6 is enabled.


149-160: Retry logic is sound.

Clearing the IPAM config on pool overlap and letting Docker auto-assign is a practical fallback. The log messages clearly communicate what's happening.

@parkervcp
Copy link
Contributor

@NaysKutzu Will this update the wings config with the new ip range once it creates properly?

@NaysKutzu
Copy link
Contributor Author

@NaysKutzu Will this update the wings config with the new ip range once it creates properly?

yes

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.

3 participants