feat: add idempotent route checks and container network routes
continuous-integration/drone/push Build is passing
continuous-integration/drone/push Build is passing
- Make AddRouteInContainer idempotent by checking existing routes and handling "File exists" errors - Add loop in firewall reconciler to add routes for containers to reach other networks - Update iptables checks to include port for better rule distinction
This commit is contained in:
@@ -215,13 +215,30 @@ func (c *Client) GetContainerPID(ctx context.Context, containerName string) (int
|
||||
return cont.State.Pid, nil
|
||||
}
|
||||
|
||||
// AddRouteInContainer adds a route inside a container's network namespace using nsenter
|
||||
// AddRouteInContainer adds a route inside a container's network namespace using nsenter.
|
||||
// Idempotent: checks if route already exists before adding.
|
||||
func (c *Client) AddRouteInContainer(ctx context.Context, containerName, network, gateway string) error {
|
||||
pid, err := c.GetContainerPID(ctx, containerName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get PID for container %s: %w", containerName, err)
|
||||
}
|
||||
|
||||
// First check if the route already exists
|
||||
checkArgs := []string{
|
||||
"-t", fmt.Sprintf("%d", pid),
|
||||
"-n", "--",
|
||||
"ip", "route", "show", network,
|
||||
}
|
||||
checkCmd := exec.Command("nsenter", checkArgs...)
|
||||
checkOutput, _ := checkCmd.CombinedOutput()
|
||||
checkStr := strings.TrimSpace(string(checkOutput))
|
||||
|
||||
// If the route exists and points to the correct gateway, skip
|
||||
if checkStr != "" && strings.Contains(checkStr, gateway) {
|
||||
logger.Debug("DOCKER: route %s via %s already exists in container %q, skipping", network, gateway, containerName)
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Info("DOCKER: adding route in container %q (PID=%d): %s via %s", containerName, pid, network, gateway)
|
||||
args := []string{
|
||||
"-t", fmt.Sprintf("%d", pid),
|
||||
@@ -232,6 +249,11 @@ func (c *Client) AddRouteInContainer(ctx context.Context, containerName, network
|
||||
cmd := exec.Command("nsenter", args...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
// "File exists" means route already exists (race condition)
|
||||
if strings.Contains(string(output), "File exists") {
|
||||
logger.Debug("DOCKER: route %s via %s already exists in container %q (File exists), skipping", network, gateway, containerName)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to add route in container %s: %w\noutput: %s", containerName, err, string(output))
|
||||
}
|
||||
logger.Info("DOCKER: route added in container %q: %s via %s", containerName, network, gateway)
|
||||
|
||||
Reference in New Issue
Block a user