diff --git a/pkg/gameservers/controller.go b/pkg/gameservers/controller.go index 67cd9f28f4..15cd0953b0 100644 --- a/pkg/gameservers/controller.go +++ b/pkg/gameservers/controller.go @@ -888,11 +888,6 @@ func (c *Controller) syncGameServerStartingState(ctx context.Context, gs *agones return gs, workerqueue.NewTraceError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name)) } - // Ensure the pod IPs are populated - if len(pod.Status.PodIPs) == 0 { - return gs, workerqueue.NewTraceError(errors.Errorf("pod IPs not yet populated for Pod %s", pod.ObjectMeta.Name)) - } - node, err := c.nodeLister.Get(pod.Spec.NodeName) if err != nil { return gs, errors.Wrapf(err, "error retrieving node %s for Pod %s", pod.Spec.NodeName, pod.ObjectMeta.Name) @@ -903,6 +898,16 @@ func (c *Controller) syncGameServerStartingState(ctx context.Context, gs *agones return gs, err } + // Ensure the pod IPs are populated + if len(pod.Status.PodIPs) == 0 { + // Update ports and address even if there is no pod IPs populated yet + gs, err = c.gameServerGetter.GameServers(gs.ObjectMeta.Namespace).Update(ctx, gsCopy, metav1.UpdateOptions{}) + if err != nil { + return gs, errors.Wrapf(err, "error updating GameServer %s address and port", gs.Name) + } + return gs, workerqueue.NewTraceError(errors.Errorf("pod IPs not yet populated for Pod %s", pod.ObjectMeta.Name)) + } + gsCopy.Status.State = agonesv1.GameServerStateScheduled gs, err = c.gameServerGetter.GameServers(gs.ObjectMeta.Namespace).Update(ctx, gsCopy, metav1.UpdateOptions{}) if err != nil { @@ -939,8 +944,14 @@ func (c *Controller) syncGameServerRequestReadyState(ctx context.Context, gs *ag // if the address hasn't been populated, and the Ready request comes // before the controller has had a chance to do it, then // do it here instead + var hasPodIPAddress bool + for _, addr := range gs.Status.Addresses { + if addr.Type == agonesv1.NodePodIP { + hasPodIPAddress = true + } + } addressPopulated := false - if gs.Status.NodeName == "" { + if gs.Status.NodeName == "" || (!hasPodIPAddress && len(pod.Status.PodIPs) > 0) { addressPopulated = true if pod.Spec.NodeName == "" { return gs, workerqueue.NewTraceError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name)) diff --git a/pkg/gameservers/controller_test.go b/pkg/gameservers/controller_test.go index 79f8ccd054..7fffd2d0e3 100644 --- a/pkg/gameservers/controller_test.go +++ b/pkg/gameservers/controller_test.go @@ -1195,6 +1195,7 @@ func TestControllerSyncGameServerStartingState(t *testing.T) { pod, err := gsFixture.Pod(agtesting.FakeAPIHooks{}) require.NoError(t, err) pod.Spec.NodeName = nodeFixtureName + pod.Status.PodIPs = nil m.KubeClient.AddReactor("list", "nodes", func(_ k8stesting.Action) (bool, runtime.Object, error) { return true, &corev1.NodeList{Items: []corev1.Node{node}}, nil @@ -1205,8 +1206,11 @@ func TestControllerSyncGameServerStartingState(t *testing.T) { m.AgonesClient.AddReactor("update", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { ua := action.(k8stesting.UpdateAction) gs := ua.GetObject().(*agonesv1.GameServer) - assert.Equal(t, agonesv1.GameServerStateScheduled, gs.Status.State) - return true, gs, errors.New("update-err") + assert.Equal(t, agonesv1.GameServerStateStarting, gs.Status.State) + assert.NotEmpty(t, gs.Status.Ports) + assert.NotEmpty(t, gs.Status.Address) + assert.NotEmpty(t, gs.Status.Addresses) + return true, gs, nil }) ctx, cancel := agtesting.StartInformers(m, c.gameServerSynced, c.podSynced, c.nodeSynced) defer cancel()