Skip to content

Commit

Permalink
Merge branch 'main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
gongmax committed Sep 19, 2024
2 parents 0518ce2 + 89038b6 commit b55f168
Show file tree
Hide file tree
Showing 20 changed files with 964 additions and 333 deletions.
1 change: 0 additions & 1 deletion build/terraform/e2e/module.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ variable "kubernetes_versions" {
description = "Create e2e test clusters with these k8s versions in these regions"
type = map(list(string))
default = {
"1.27" = ["us-east1", "RAPID"]
"1.28" = ["us-west1", "RAPID"]
"1.29" = ["europe-west1", "RAPID"]
"1.30" = ["asia-east1", "RAPID"]
Expand Down
2 changes: 1 addition & 1 deletion build/terraform/performance/module.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ variable "kubernetes_versions" {
description = "Create performance test clusters with these k8s versions in these regions"
type = map(list(string))
default = {
"1.28" = ["us-central1", "RAPID"]
"1.29" = ["us-central1", "RAPID"]
}
}

Expand Down
2 changes: 1 addition & 1 deletion ci/perf-test-cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ steps:
- tag-build-image

substitutions:
_TEST_CLUSTER_NAME: standard-performance-test-cluster-1-28
_TEST_CLUSTER_NAME: standard-performance-test-cluster-1-29
_TEST_CLUSTER_LOCATION: us-central1
_REGISTRY: us-docker.pkg.dev/agones-images/ci
_TEST_PROJECT_ID: agones-images
Expand Down
12 changes: 6 additions & 6 deletions pkg/gameservers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -878,19 +878,19 @@ func (c *Controller) syncGameServerStartingState(ctx context.Context, gs *agones
if err != nil {
// expected to happen, so don't log it.
if k8serrors.IsNotFound(err) {
return nil, workerqueue.NewDebugError(err)
return nil, workerqueue.NewTraceError(err)
}

// do log if it's something other than NotFound, since that's weird.
return nil, err
}
if pod.Spec.NodeName == "" {
return gs, workerqueue.NewDebugError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name))
return gs, workerqueue.NewTraceError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name))
}

// Ensure the pod IPs are populated
if pod.Status.PodIPs == nil || len(pod.Status.PodIPs) == 0 {
return gs, workerqueue.NewDebugError(errors.Errorf("pod IPs not yet populated for Pod %s", pod.ObjectMeta.Name))
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)
Expand Down Expand Up @@ -943,7 +943,7 @@ func (c *Controller) syncGameServerRequestReadyState(ctx context.Context, gs *ag
if gs.Status.NodeName == "" {
addressPopulated = true
if pod.Spec.NodeName == "" {
return gs, workerqueue.NewDebugError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name))
return gs, workerqueue.NewTraceError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name))
}
node, err := c.nodeLister.Get(pod.Spec.NodeName)
if err != nil {
Expand All @@ -963,7 +963,7 @@ func (c *Controller) syncGameServerRequestReadyState(ctx context.Context, gs *ag
// check to make sure this container is actually running. If there was a recent crash, the cache may
// not yet have the newer, running container.
if cs.State.Running == nil {
return nil, workerqueue.NewDebugError(fmt.Errorf("game server container for GameServer %s in namespace %s is not currently running, try again", gsCopy.ObjectMeta.Name, gsCopy.ObjectMeta.Namespace))
return nil, workerqueue.NewTraceError(fmt.Errorf("game server container for GameServer %s in namespace %s is not currently running, try again", gsCopy.ObjectMeta.Name, gsCopy.ObjectMeta.Namespace))
}
gsCopy.ObjectMeta.Annotations[agonesv1.GameServerReadyContainerIDAnnotation] = cs.ContainerID
}
Expand All @@ -972,7 +972,7 @@ func (c *Controller) syncGameServerRequestReadyState(ctx context.Context, gs *ag
}
// Verify that we found the game server container - we may have a stale cache where pod is missing ContainerStatuses.
if _, ok := gsCopy.ObjectMeta.Annotations[agonesv1.GameServerReadyContainerIDAnnotation]; !ok {
return nil, workerqueue.NewDebugError(fmt.Errorf("game server container for GameServer %s in namespace %s not present in pod status, try again", gsCopy.ObjectMeta.Name, gsCopy.ObjectMeta.Namespace))
return nil, workerqueue.NewTraceError(fmt.Errorf("game server container for GameServer %s in namespace %s not present in pod status, try again", gsCopy.ObjectMeta.Name, gsCopy.ObjectMeta.Namespace))
}

// Also update the pod with the same annotation, so we can check if the Pod data is up-to-date, now and also in the HealthController.
Expand Down
2 changes: 1 addition & 1 deletion pkg/gameservers/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func (hc *HealthController) skipUnhealthyGameContainer(gs *agonesv1.GameServer,
// in which case, send it back to the queue to try again.
gsReadyContainerID := gs.ObjectMeta.Annotations[agonesv1.GameServerReadyContainerIDAnnotation]
if pod.ObjectMeta.Annotations[agonesv1.GameServerReadyContainerIDAnnotation] != gsReadyContainerID {
return false, workerqueue.NewDebugError(errors.Errorf("pod and gameserver %s data are out of sync, retrying", gs.ObjectMeta.Name))
return false, workerqueue.NewTraceError(errors.Errorf("pod and gameserver %s data are out of sync, retrying", gs.ObjectMeta.Name))
}

if gs.IsBeforeReady() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/gameservers/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (mc *MigrationController) isMigratingGameServerPod(pod *k8sv1.Pod) (*agones
}

if pod.Spec.NodeName == "" {
return nil, nil, false, workerqueue.NewDebugError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name))
return nil, nil, false, workerqueue.NewTraceError(errors.Errorf("node not yet populated for Pod %s", pod.ObjectMeta.Name))
}

node, err := mc.nodeLister.Get(pod.Spec.NodeName)
Expand Down
8 changes: 7 additions & 1 deletion pkg/sdkserver/sdkserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -459,7 +460,12 @@ func (s *SDKServer) patchGameServer(ctx context.Context, gs, gsCopy *agonesv1.Ga
return nil, err
}

return s.gameServerGetter.GameServers(s.namespace).Patch(ctx, gs.GetObjectMeta().GetName(), types.JSONPatchType, patch, metav1.PatchOptions{})
gs, err = s.gameServerGetter.GameServers(s.namespace).Patch(ctx, gs.GetObjectMeta().GetName(), types.JSONPatchType, patch, metav1.PatchOptions{})
// if the test operation fails, no reason to error log
if err != nil && k8serrors.IsInvalid(err) {
err = workerqueue.NewTraceError(err)
}
return gs, errors.Wrapf(err, "error attempting to patch gameserver: %s/%s", gsCopy.ObjectMeta.Namespace, gsCopy.ObjectMeta.Name)
}

// updateLabels updates the labels on this GameServer to the ones persisted in SDKServer,
Expand Down
22 changes: 11 additions & 11 deletions pkg/util/workerqueue/workerqueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,29 @@ const (
workFx = time.Second
)

// debugError is a marker type for errors that that should only be logged at a Debug level.
// traceError is a marker type for errors that that should only be logged at a Trace level.
// Useful if you want a Handler to be retried, but not logged at an Error level.
type debugError struct {
type traceError struct {
err error
}

// NewDebugError returns a debugError wrapper around an error.
func NewDebugError(err error) error {
return &debugError{err: err}
// NewTraceError returns a traceError wrapper around an error.
func NewTraceError(err error) error {
return &traceError{err: err}
}

// Error returns the error string
func (l *debugError) Error() string {
func (l *traceError) Error() string {
if l.err == nil {
return "<nil>"
}
return l.err.Error()
}

// isDebugError returns if the error is a debug error or not
func isDebugError(err error) bool {
// isTraceError returns if the error is a trace error or not
func isTraceError(err error) bool {
cause := errors.Cause(err)
_, ok := cause.(*debugError)
_, ok := cause.(*traceError)
return ok
}

Expand Down Expand Up @@ -181,8 +181,8 @@ func (wq *WorkerQueue) processNextWorkItem(ctx context.Context) bool {

if err := wq.SyncHandler(ctx, key); err != nil {
// Conflicts are expected, so only show them in debug operations.
// Also check is debugError for other expected errors.
if k8serror.IsConflict(errors.Cause(err)) || isDebugError(err) {
// Also check is traceError for other expected errors.
if k8serror.IsConflict(errors.Cause(err)) || isTraceError(err) {
wq.logger.WithField(wq.keyName, obj).Trace(err)
} else {
runtime.HandleError(wq.logger.WithField(wq.keyName, obj), err)
Expand Down
10 changes: 5 additions & 5 deletions pkg/util/workerqueue/workerqueue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,13 @@ func TestWorkerQueueEnqueueAfter(t *testing.T) {

func TestDebugError(t *testing.T) {
err := errors.New("not a debug error")
assert.False(t, isDebugError(err))
assert.False(t, isTraceError(err))

err = NewDebugError(err)
assert.True(t, isDebugError(err))
err = NewTraceError(err)
assert.True(t, isTraceError(err))
assert.EqualError(t, err, "not a debug error")

err = NewDebugError(nil)
assert.True(t, isDebugError(err))
err = NewTraceError(nil)
assert.True(t, isTraceError(err))
assert.EqualError(t, err, "<nil>")
}
40 changes: 40 additions & 0 deletions test/sdk/go/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2024 Google LLC All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Build the Go image from source
FROM golang:1.22.6 AS build-stage

WORKDIR /agones.dev

COPY *.go ./

# Note: because this installs the most recently released version of Agones, this will need to be
# built and pushed post-release.
# TODO: Add to post-release check list.
RUN go mod init agones.dev/agones/test/sdk/go/sdk-client-test
RUN go mod tidy
RUN go mod download

RUN CGO_ENABLED=0 GOOS=linux go build -o /sdk-client-test

# Copy the above binary into a lean image
FROM gcr.io/distroless/static-debian12:nonroot AS build-release-stage

WORKDIR /

COPY --from=build-stage /sdk-client-test /sdk-client-test

USER nonroot:nonroot

ENTRYPOINT ["/sdk-client-test"]
51 changes: 51 additions & 0 deletions test/sdk/go/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2024 Google LLC All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# Makefile for building a test game-server
#

# __ __ _ _ _
# \ \ / /_ _ _ __(_) __ _| |__ | | ___ ___
# \ \ / / _` | '__| |/ _` | '_ \| |/ _ \ __|
# \ V / (_| | | | | (_| | |_) | | __\__ \
# \_/ \__,_|_| |_|\__,_|_.__/|_|\___|___/
#

REGISTRY ?=
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
project_path := $(dir $(mkfile_path))
root_path = $(realpath $(project_path)/)
# Because go mod init in the Dockerfile installs the most recently released version of Agones, this
# will need to be built and pushed post-release. During DEV it will be built at DEV - 1.
base_version = 1.43.0
server_tag := $(REGISTRY)/sdk-client-test:$(base_version)

# _____ _
# |_ _|_ _ _ __ __ _ ___| |_ ___
# | |/ _` | '__/ _` |/ _ \ __/ __|
# | | (_| | | | (_| | __/ |_\__ \
# |_|\__,_|_| \__, |\___|\__|___/
# |___/

# Build a docker image for the server, and tag it
build:
cd $(root_path) && docker build -f $(project_path)Dockerfile --tag=$(server_tag) .

push: build
docker push $(server_tag)

# build and push the sdk-client-test image with specified tag
cloud-build:
cd $(root_path) && gcloud builds submit --config=cloudbuild.yaml
38 changes: 38 additions & 0 deletions test/sdk/go/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
steps:
#
# Creates the initial make + docker build platform
#
- name: ubuntu
script: |
echo 'FROM gcr.io/cloud-builders/docker:24.0.6\nRUN apt-get install make\nENTRYPOINT [\"/usr/bin/make\"]' > Dockerfile.build
- name: gcr.io/cloud-builders/docker:24.0.6
id: build-make-docker
entrypoint: docker
args: [build, -f, Dockerfile.build, -t, make-docker, .]

# build and push sdk-client-test image to Google Artifact Registry
- name: make-docker
id: push
dir: .
env: ['REGISTRY=${_REGISTRY}']
script: |
make push
options:
dynamic_substitutions: true
substitutions:
_REGISTRY: us-docker.pkg.dev/${PROJECT_ID}/ci
timeout: 1800s
30 changes: 27 additions & 3 deletions test/upgrade/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,39 @@
# See the License for the specific language governing permissions and
# limitations under the License.

FROM gcr.io/cloud-builders/gcloud AS builder

RUN apt-get update && \
apt-get clean

WORKDIR /usr/local

# install kubectl
ENV KUBECTL_VER=1.29.7
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VER}/bin/linux/amd64/kubectl && \
chmod go+rx ./kubectl && \
mv ./kubectl /usr/local/bin/kubectl

# install Helm package manager
ENV HELM_VER=3.14.3
ENV HELM_URL=https://get.helm.sh/helm-v${HELM_VER}-linux-amd64.tar.gz
RUN curl -L ${HELM_URL} > /tmp/helm.tar.gz \
&& tar -zxvf /tmp/helm.tar.gz -C /tmp \
&& mv /tmp/linux-amd64/helm /usr/local/bin/helm \
&& chmod go+rx /usr/local/bin/helm \
&& rm /tmp/helm.tar.gz && rm -rf /tmp/linux-amd64

# Build the Go image from source
FROM golang:1.22.6 AS build-stage

WORKDIR /agones.dev

COPY go.mod go.sum ./
RUN go mod download

COPY *.go ./

RUN go mod init agones.dev/agones/test/upgrade/testContainer
RUN go mod tidy
RUN go mod download

RUN CGO_ENABLED=0 GOOS=linux go build -o /upgrade-test

# Copy the above binary into a lean image
Expand All @@ -30,6 +53,7 @@ FROM gcr.io/distroless/static-debian12:nonroot AS build-release-stage
WORKDIR /

COPY --from=build-stage /upgrade-test /upgrade-test
COPY --from=builder /usr/local /usr/local

USER nonroot:nonroot

Expand Down
Loading

0 comments on commit b55f168

Please sign in to comment.