diff --git a/test/infrastructure/docker/internal/docker/loadbalancer.go b/test/infrastructure/docker/internal/docker/loadbalancer.go index b590b1b6c621..288f058be425 100644 --- a/test/infrastructure/docker/internal/docker/loadbalancer.go +++ b/test/infrastructure/docker/internal/docker/loadbalancer.go @@ -191,6 +191,17 @@ func (s *LoadBalancer) UpdateConfiguration(ctx context.Context, unsafeLoadBalanc return errors.WithStack(err) } + // Read back the load balancer configuration to ensure it got written before + // signaling haproxy to reload the config file. + // This is a workaround to fix https://github.com/kubernetes-sigs/cluster-api/issues/10356 + readLoadBalancerConfig, err := s.container.ReadFile(ctx, loadbalancer.ConfigPath) + if err != nil { + return errors.WithStack(err) + } + if string(readLoadBalancerConfig) != loadBalancerConfig { + return fmt.Errorf("read load balancer configuration does not match written file") + } + return errors.WithStack(s.container.Kill(ctx, "SIGHUP")) } diff --git a/test/infrastructure/docker/internal/docker/types/node.go b/test/infrastructure/docker/internal/docker/types/node.go index 202e9e4ad0e7..de220cc0436b 100644 --- a/test/infrastructure/docker/internal/docker/types/node.go +++ b/test/infrastructure/docker/internal/docker/types/node.go @@ -120,6 +120,21 @@ func (n *Node) Delete(ctx context.Context) error { return nil } +// ReadFile reads a file from a running container. +func (n *Node) ReadFile(ctx context.Context, dest string) ([]byte, error) { + command := n.Commander.Command("cp", dest, "/dev/stdout") + stdout := bytes.Buffer{} + + command.SetStdout(&stdout) + // Also set stderr so it does not pollute stdout. + command.SetStderr(&bytes.Buffer{}) + + if err := command.Run(ctx); err != nil { + return nil, errors.Wrapf(err, "failed to read file %s", dest) + } + return stdout.Bytes(), nil +} + // WriteFile puts a file inside a running container. func (n *Node) WriteFile(ctx context.Context, dest, content string) error { // create destination directory