Add feature: Service Quality (#11)

Service Quality support
This commit is contained in:
ChrisLiu 2022-11-01 11:46:06 +08:00 committed by GitHub
parent 4fc797b9d0
commit f563275284
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 701 additions and 145 deletions

View File

@ -47,7 +47,7 @@ jobs:
make helm
helm repo add openkruise https://openkruise.github.io/charts/
helm repo update
helm install kruise openkruise/kruise
helm install kruise openkruise/kruise --version 1.3.0 --set featureGates="PodProbeMarkerGate=true"
for ((i=1;i<10;i++));
do
set +e

View File

@ -58,9 +58,13 @@ const (
)
type ServiceQuality struct {
corev1.Probe `json:",inline"`
Name string `json:"name"`
ContainerName string `json:"containerName,omitempty"`
corev1.Probe `json:",inline"`
Name string `json:"name"`
ContainerName string `json:"containerName,omitempty"`
// Whether to make GameServerSpec not change after the ServiceQualityAction is executed.
// When Permanent is true, regardless of the detection results, ServiceQualityAction will only be executed once.
// When Permanent is false, ServiceQualityAction can be executed again even though ServiceQualityAction has been executed.
Permanent bool `json:"permanent"`
ServiceQualityAction []ServiceQualityAction `json:"serviceQualityAction,omitempty"`
}
@ -73,7 +77,6 @@ type ServiceQualityCondition struct {
}
type ServiceQualityAction struct {
Permanent bool `json:"permanent,omitempty"` // default: true
State bool `json:"state"`
GameServerSpec `json:",inline"`
}

View File

@ -29,10 +29,10 @@ import (
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
const (
GameServerOwnerGssKey = "game.kruise.io/owner-gss"
GameServerSetReserveIdsKey = "game.kruise.io/reserve-ids"
GameServerSetNotExistIdsKey = "game.kruise.io/not-exist-ids"
AstsHashKey = "game.kruise.io/asts-hash"
GameServerOwnerGssKey = "game.kruise.io/owner-gss"
GameServerSetReserveIdsKey = "game.kruise.io/reserve-ids"
AstsHashKey = "game.kruise.io/asts-hash"
PpmHashKey = "game.kruise.io/ppm-hash"
)
// GameServerSetSpec defines the desired state of GameServerSet

View File

@ -472,6 +472,14 @@ spec:
to 10 seconds. Minimum value is 1.
format: int32
type: integer
permanent:
description: Whether to make GameServerSpec not change after
the ServiceQualityAction is executed. When Permanent is true,
regardless of the detection results, ServiceQualityAction
will only be executed once. When Permanent is false, ServiceQualityAction
can be executed again even though ServiceQualityAction has
been executed.
type: boolean
serviceQualityAction:
items:
properties:
@ -484,8 +492,6 @@ spec:
type: boolean
opsState:
type: string
permanent:
type: boolean
state:
type: boolean
updatePriority:
@ -545,6 +551,7 @@ spec:
type: integer
required:
- name
- permanent
type: object
type: array
updateStrategy:

View File

@ -37,6 +37,18 @@ rules:
- patch
- update
- watch
- apiGroups:
- apps.kruise.io
resources:
- podprobemarkers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apps.kruise.io
resources:

2
go.mod
View File

@ -6,7 +6,7 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.18.1
github.com/openkruise/kruise-api v1.2.0
github.com/openkruise/kruise-api v1.3.0
k8s.io/api v0.24.0
k8s.io/apimachinery v0.24.0
k8s.io/client-go v0.24.0

40
go.sum
View File

@ -41,19 +41,14 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM=
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
@ -123,7 +118,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@ -139,7 +133,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@ -153,7 +146,6 @@ github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWp
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -170,16 +162,12 @@ github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk=
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
@ -263,12 +251,10 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
@ -332,14 +318,12 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -380,7 +364,6 @@ github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
@ -389,14 +372,13 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/openkruise/kruise-api v1.2.0 h1:MhoQtYT2tRdjrpb51xhn3lhEDWSlRGiMYQQ0Sh3zCkk=
github.com/openkruise/kruise-api v1.2.0/go.mod h1:BKMffjLFufZkj/yVpF5TjXG9gMU3Y9A3FxrVOJ5LJUI=
github.com/openkruise/kruise-api v1.3.0 h1:yfEy64uXgSuX/5RwePLbwUK/uX8RRM8fHJkccel5ZIQ=
github.com/openkruise/kruise-api v1.3.0/go.mod h1:9ZX+ycdHKNzcA5ezAf35xOa2Mwfa2BYagWr0lKgi5dU=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@ -462,7 +444,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@ -470,7 +451,6 @@ github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5q
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -538,7 +518,6 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -672,7 +651,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -702,7 +680,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -743,7 +720,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -760,7 +736,6 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
@ -965,37 +940,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.20.15/go.mod h1:X3JDf1BiTRQQ6xNAxTuhgi6yL2dHc6fSr9LGzE+Z3YU=
k8s.io/api v0.24.0 h1:J0hann2hfxWr1hinZIDefw7Q96wmCBx6SSB8IY0MdDg=
k8s.io/api v0.24.0/go.mod h1:5Jl90IUrJHUJYEMANRURMiVvJ0g7Ax7r3R1bqO8zx8I=
k8s.io/apiextensions-apiserver v0.24.0 h1:JfgFqbA8gKJ/uDT++feAqk9jBIwNnL9YGdQvaI9DLtY=
k8s.io/apiextensions-apiserver v0.24.0/go.mod h1:iuVe4aEpe6827lvO6yWQVxiPSpPoSKVjkq+MIdg84cM=
k8s.io/apimachinery v0.20.15/go.mod h1:4KFiDSxCoGviCiRk9kTXIROsIf4VSGkVYjVJjJln3pg=
k8s.io/apimachinery v0.24.0 h1:ydFCyC/DjCvFCHK5OPMKBlxayQytB8pxy8YQInd5UyQ=
k8s.io/apimachinery v0.24.0/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
k8s.io/apiserver v0.24.0/go.mod h1:WFx2yiOMawnogNToVvUYT9nn1jaIkMKj41ZYCVycsBA=
k8s.io/client-go v0.20.15/go.mod h1:q/vywQFfGT3jw+lXQGA9sEJDH0QEX7XUT2PwrQ2qm/I=
k8s.io/client-go v0.24.0 h1:lbE4aB1gTHvYFSwm6eD3OF14NhFDKCejlnsGYlSJe5U=
k8s.io/client-go v0.24.0/go.mod h1:VFPQET+cAFpYxh6Bq6f4xyMY80G6jKKktU6G0m00VDw=
k8s.io/code-generator v0.20.15/go.mod h1:MW85KuhTjX9nzhFYpRqUOYh4et0xeEBHTEjwBzFYGaM=
k8s.io/code-generator v0.24.0 h1:7v52LjqCntfGxV9x8c57gkhDqkMHd0Z2jfRqGr6it6g=
k8s.io/code-generator v0.24.0/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
k8s.io/component-base v0.24.0 h1:h5jieHZQoHrY/lHG+HyrSbJeyfuitheBvqvKwKHVC0g=
k8s.io/component-base v0.24.0/go.mod h1:Dgazgon0i7KYUsS8krG8muGiMVtUZxG037l1MKyXgrA=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI=
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc=
k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20211110013926-83f114cd0513/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU=
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
@ -1008,10 +974,8 @@ sigs.k8s.io/controller-runtime v0.12.1/go.mod h1:BKhxlA4l7FPK4AQcsuL4X6vZeWnKDXe
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View File

@ -18,6 +18,7 @@ package main
import (
"flag"
kruiseV1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseV1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
controller "github.com/openkruise/kruise-game/pkg/controllers"
"github.com/openkruise/kruise-game/pkg/webhook"
@ -50,6 +51,7 @@ func init() {
utilruntime.Must(gamekruiseiov1alpha1.AddToScheme(scheme))
utilruntime.Must(kruiseV1beta1.AddToScheme(scheme))
utilruntime.Must(kruiseV1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}

View File

@ -39,6 +39,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
"time"
)
var (
@ -185,12 +186,12 @@ func (r *GameServerReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return reconcile.Result{}, err
}
podUpdated, err := gsm.SyncToPod()
podUpdated, err := gsm.SyncGsToPod()
if err != nil || podUpdated {
return reconcile.Result{Requeue: podUpdated}, err
return reconcile.Result{Requeue: podUpdated, RequeueAfter: 3 * time.Second}, err
}
err = gsm.SyncToGs(gss.Spec.ServiceQualities)
err = gsm.SyncPodToGs(gss)
if err != nil {
return reconcile.Result{}, err
}

View File

@ -33,8 +33,12 @@ import (
)
type Control interface {
SyncToPod() (bool, error)
SyncToGs(qualities []gameKruiseV1alpha1.ServiceQuality) error
// SyncGsToPod compares the pod with GameServer, and decide whether to update the pod based on the results.
// When the fields of the pod is different from that of GameServer,
// pod will be updated and true is returned; otherwise, the pod won't be updated and false is returned.
SyncGsToPod() (bool, error)
// SyncPodToGs compares the GameServer with pod, and update the GameServer.
SyncPodToGs(*gameKruiseV1alpha1.GameServerSet) error
}
type GameServerManager struct {
@ -43,8 +47,7 @@ type GameServerManager struct {
client client.Client
}
func (manager GameServerManager) SyncToPod() (bool, error) {
// compare GameServer Spec With Pod
func (manager GameServerManager) SyncGsToPod() (bool, error) {
pod := manager.pod
gs := manager.gameServer
podLabels := pod.GetLabels()
@ -83,15 +86,14 @@ func (manager GameServerManager) SyncToPod() (bool, error) {
break
}
// GameServer Ready / NotReady
for _, con := range pod.Status.Conditions {
if con.Type == corev1.PodReady {
if con.Status == corev1.ConditionTrue {
gsState = gameKruiseV1alpha1.Ready
} else {
gsState = gameKruiseV1alpha1.NotReady
}
break
_, condition := util.GetPodConditionFromList(pod.Status.Conditions, corev1.PodReady)
if condition != nil {
if condition.Status == corev1.ConditionTrue {
gsState = gameKruiseV1alpha1.Ready
} else {
gsState = gameKruiseV1alpha1.NotReady
}
break
}
case corev1.PodFailed:
gsState = gameKruiseV1alpha1.Crash
@ -121,78 +123,32 @@ func (manager GameServerManager) SyncToPod() (bool, error) {
return updated, nil
}
func (manager GameServerManager) SyncToGs(qualities []gameKruiseV1alpha1.ServiceQuality) error {
func (manager GameServerManager) SyncPodToGs(gss *gameKruiseV1alpha1.GameServerSet) error {
gs := manager.gameServer
pod := manager.pod
// sync DeletePriority/UpdatePriority/State
podLabels := pod.GetLabels()
podDeletePriority := intstr.FromString(podLabels[gameKruiseV1alpha1.GameServerDeletePriorityKey])
podUpdatePriority := intstr.FromString(podLabels[gameKruiseV1alpha1.GameServerUpdatePriorityKey])
podGsState := gameKruiseV1alpha1.GameServerState(podLabels[gameKruiseV1alpha1.GameServerStateKey])
gsConditions := gs.Status.ServiceQualitiesCondition
podConditions := pod.Status.Conditions
var sqNames []string
for _, sq := range qualities {
sqNames = append(sqNames, sq.Name)
}
var toExec map[string]string
var newGsConditions []gameKruiseV1alpha1.ServiceQualityCondition
for _, pc := range podConditions {
if util.IsStringInList(string(pc.Type), sqNames) {
toExecAction := true
lastActionTransitionTime := metav1.Now()
for _, gsc := range gsConditions {
if gsc.Name == string(pc.Type) && gsc.Status == string(pc.Status) {
toExecAction = false
lastActionTransitionTime = gsc.LastActionTransitionTime
break
}
}
serviceQualityCondition := gameKruiseV1alpha1.ServiceQualityCondition{
Name: string(pc.Type),
Status: string(pc.Status),
LastProbeTime: pc.LastProbeTime,
LastTransitionTime: pc.LastTransitionTime,
LastActionTransitionTime: lastActionTransitionTime,
}
newGsConditions = append(newGsConditions, serviceQualityCondition)
if toExecAction {
if toExec == nil {
toExec = make(map[string]string)
}
toExec[string(pc.Type)] = string(pc.Status)
}
}
}
if toExec != nil {
var spec gameKruiseV1alpha1.GameServerSpec
for _, sq := range qualities {
for name, state := range toExec {
if sq.Name == name {
for _, action := range sq.ServiceQualityAction {
if state == strconv.FormatBool(action.State) {
spec.DeletionPriority = action.DeletionPriority
spec.UpdatePriority = action.UpdatePriority
spec.OpsState = action.OpsState
spec.NetworkDisabled = action.NetworkDisabled
}
}
}
}
}
// sync Service Qualities
spec, newGsConditions := syncServiceQualities(gss.Spec.ServiceQualities, pod.Status.Conditions, gs.Status.ServiceQualitiesCondition)
patchSpec := map[string]interface{}{"spec": spec}
jsonPatchSpec, err := json.Marshal(patchSpec)
if err != nil {
return err
}
err = manager.client.Patch(context.TODO(), gs, client.RawPatch(types.MergePatchType, jsonPatchSpec))
if err != nil && !errors.IsNotFound(err) {
klog.Errorf("failed to patch GameServer spec %s in %s,because of %s.", gs.GetName(), gs.GetNamespace(), err.Error())
return err
}
// patch gs spec
patchSpec := map[string]interface{}{"spec": spec}
jsonPatchSpec, err := json.Marshal(patchSpec)
if err != nil {
return err
}
err = manager.client.Patch(context.TODO(), gs, client.RawPatch(types.MergePatchType, jsonPatchSpec))
if err != nil && !errors.IsNotFound(err) {
klog.Errorf("failed to patch GameServer spec %s in %s,because of %s.", gs.GetName(), gs.GetNamespace(), err.Error())
return err
}
// patch gs status
status := gameKruiseV1alpha1.GameServerStatus{
PodStatus: pod.Status,
CurrentState: podGsState,
@ -216,6 +172,45 @@ func (manager GameServerManager) SyncToGs(qualities []gameKruiseV1alpha1.Service
return nil
}
func syncServiceQualities(serviceQualities []gameKruiseV1alpha1.ServiceQuality, podConditions []corev1.PodCondition, sqConditions []gameKruiseV1alpha1.ServiceQualityCondition) (gameKruiseV1alpha1.GameServerSpec, []gameKruiseV1alpha1.ServiceQualityCondition) {
var spec gameKruiseV1alpha1.GameServerSpec
var newGsConditions []gameKruiseV1alpha1.ServiceQualityCondition
sqConditionsMap := make(map[string]gameKruiseV1alpha1.ServiceQualityCondition)
for _, sqc := range sqConditions {
sqConditionsMap[sqc.Name] = sqc
}
for _, sq := range serviceQualities {
var newSqCondition gameKruiseV1alpha1.ServiceQualityCondition
newSqCondition.Name = sq.Name
index, podCondition := util.GetPodConditionFromList(podConditions, corev1.PodConditionType(util.AddPrefixGameKruise(sq.Name)))
if index != -1 {
newSqCondition.Status = string(podCondition.Status)
newSqCondition.LastProbeTime = podCondition.LastProbeTime
var lastActionTransitionTime metav1.Time
sqCondition, exist := sqConditionsMap[sq.Name]
if !exist || (sqCondition.Status != string(podCondition.Status) && (sqCondition.LastActionTransitionTime.IsZero() || !sq.Permanent)) {
// exec action
for _, action := range sq.ServiceQualityAction {
state, err := strconv.ParseBool(string(podCondition.Status))
if err == nil && state == action.State {
spec.DeletionPriority = action.DeletionPriority
spec.UpdatePriority = action.UpdatePriority
spec.OpsState = action.OpsState
spec.NetworkDisabled = action.NetworkDisabled
lastActionTransitionTime = metav1.Now()
}
}
} else {
lastActionTransitionTime = sqCondition.LastActionTransitionTime
}
newSqCondition.LastActionTransitionTime = lastActionTransitionTime
}
newSqCondition.LastTransitionTime = metav1.Now()
newGsConditions = append(newGsConditions, newSqCondition)
}
return spec, newGsConditions
}
func NewGameServerManager(gs *gameKruiseV1alpha1.GameServer, pod *corev1.Pod, c client.Client) Control {
return &GameServerManager{
gameServer: gs,

View File

@ -0,0 +1,281 @@
package gameserver
import (
gameKruiseV1alpha1 "github.com/openkruise/kruise-game/apis/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"reflect"
"testing"
)
func TestSyncServiceQualities(t *testing.T) {
up := intstr.FromInt(20)
dp := intstr.FromInt(10)
fakeProbeTime := metav1.Now()
fakeActionTime := metav1.Now()
tests := []struct {
serviceQualities []gameKruiseV1alpha1.ServiceQuality
podConditions []corev1.PodCondition
sqConditions []gameKruiseV1alpha1.ServiceQualityCondition
spec gameKruiseV1alpha1.GameServerSpec
newSqConditions []gameKruiseV1alpha1.ServiceQualityCondition
}{
{
serviceQualities: []gameKruiseV1alpha1.ServiceQuality{
{
Name: "healthy",
Permanent: true,
ServiceQualityAction: []gameKruiseV1alpha1.ServiceQualityAction{
{
State: true,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
UpdatePriority: &up,
},
},
{
State: false,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
DeletionPriority: &dp,
},
},
},
},
},
podConditions: []corev1.PodCondition{
{
Type: "game.kruise.io/healthy",
Status: corev1.ConditionTrue,
LastProbeTime: fakeProbeTime,
},
{
Type: "otherA",
Status: corev1.ConditionFalse,
LastProbeTime: fakeProbeTime,
},
},
sqConditions: nil,
spec: gameKruiseV1alpha1.GameServerSpec{
UpdatePriority: &up,
},
newSqConditions: []gameKruiseV1alpha1.ServiceQualityCondition{
{
Name: "healthy",
Status: string(corev1.ConditionTrue),
LastProbeTime: fakeProbeTime,
LastActionTransitionTime: fakeActionTime,
},
},
},
{
serviceQualities: []gameKruiseV1alpha1.ServiceQuality{
{
Name: "healthy",
Permanent: true,
ServiceQualityAction: []gameKruiseV1alpha1.ServiceQualityAction{
{
State: true,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
UpdatePriority: &up,
},
},
{
State: false,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
DeletionPriority: &dp,
},
},
},
},
},
podConditions: []corev1.PodCondition{
{
Type: "game.kruise.io/healthy",
Status: corev1.ConditionTrue,
LastProbeTime: fakeProbeTime,
},
{
Type: "otherA",
Status: corev1.ConditionFalse,
LastProbeTime: fakeProbeTime,
},
},
sqConditions: []gameKruiseV1alpha1.ServiceQualityCondition{
{
Name: "healthy",
Status: string(corev1.ConditionFalse),
LastProbeTime: fakeProbeTime,
LastActionTransitionTime: fakeActionTime,
},
},
spec: gameKruiseV1alpha1.GameServerSpec{},
newSqConditions: []gameKruiseV1alpha1.ServiceQualityCondition{
{
Name: "healthy",
Status: string(corev1.ConditionTrue),
LastProbeTime: fakeProbeTime,
LastActionTransitionTime: fakeActionTime,
},
},
},
{
serviceQualities: []gameKruiseV1alpha1.ServiceQuality{
{
Name: "healthy",
Permanent: true,
ServiceQualityAction: []gameKruiseV1alpha1.ServiceQualityAction{
{
State: true,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
UpdatePriority: &up,
},
},
{
State: false,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
DeletionPriority: &dp,
},
},
},
},
},
podConditions: []corev1.PodCondition{
{
Type: "otherA",
Status: corev1.ConditionFalse,
LastProbeTime: fakeProbeTime,
},
},
sqConditions: nil,
spec: gameKruiseV1alpha1.GameServerSpec{},
newSqConditions: []gameKruiseV1alpha1.ServiceQualityCondition{
{
Name: "healthy",
},
},
},
{
serviceQualities: []gameKruiseV1alpha1.ServiceQuality{
{
Name: "healthy",
Permanent: true,
ServiceQualityAction: []gameKruiseV1alpha1.ServiceQualityAction{
{
State: true,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
UpdatePriority: &up,
},
},
},
},
},
podConditions: []corev1.PodCondition{
{
Type: "game.kruise.io/healthy",
Status: corev1.ConditionFalse,
LastProbeTime: fakeProbeTime,
},
{
Type: "otherA",
Status: corev1.ConditionFalse,
LastProbeTime: fakeProbeTime,
},
},
sqConditions: nil,
spec: gameKruiseV1alpha1.GameServerSpec{},
newSqConditions: []gameKruiseV1alpha1.ServiceQualityCondition{
{
Name: "healthy",
Status: string(corev1.ConditionFalse),
LastProbeTime: fakeProbeTime,
},
},
},
{
serviceQualities: []gameKruiseV1alpha1.ServiceQuality{
{
Name: "healthy",
Permanent: false,
ServiceQualityAction: []gameKruiseV1alpha1.ServiceQualityAction{
{
State: true,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
UpdatePriority: &up,
},
},
{
State: false,
GameServerSpec: gameKruiseV1alpha1.GameServerSpec{
DeletionPriority: &dp,
},
},
},
},
},
podConditions: []corev1.PodCondition{
{
Type: "game.kruise.io/healthy",
Status: corev1.ConditionTrue,
LastProbeTime: fakeProbeTime,
},
{
Type: "otherA",
Status: corev1.ConditionFalse,
LastProbeTime: fakeProbeTime,
},
},
sqConditions: []gameKruiseV1alpha1.ServiceQualityCondition{
{
Name: "healthy",
Status: string(corev1.ConditionFalse),
LastProbeTime: fakeProbeTime,
LastActionTransitionTime: fakeActionTime,
},
},
spec: gameKruiseV1alpha1.GameServerSpec{
UpdatePriority: &up,
},
newSqConditions: []gameKruiseV1alpha1.ServiceQualityCondition{
{
Name: "healthy",
Status: string(corev1.ConditionTrue),
LastProbeTime: fakeProbeTime,
LastActionTransitionTime: fakeActionTime,
},
},
},
}
for _, test := range tests {
actualSpec, actualNewSqConditions := syncServiceQualities(test.serviceQualities, test.podConditions, test.sqConditions)
expectSpec := test.spec
expectNewSqConditions := test.newSqConditions
if !reflect.DeepEqual(actualSpec, expectSpec) {
t.Errorf("expect spec %v but got %v", expectSpec, actualSpec)
}
if len(actualNewSqConditions) != len(expectNewSqConditions) {
t.Errorf("expect sq conditions len %v but got %v", len(expectNewSqConditions), len(actualNewSqConditions))
}
for _, expectNewSqCondition := range expectNewSqConditions {
exist := false
for _, actualNewSqCondition := range actualNewSqConditions {
if actualNewSqCondition.Name == expectNewSqCondition.Name {
exist = true
if actualNewSqCondition.Status != expectNewSqCondition.Status {
t.Errorf("expect sq condition status %v but got %v", expectNewSqCondition.Status, actualNewSqCondition.Status)
}
if actualNewSqCondition.LastProbeTime != expectNewSqCondition.LastProbeTime {
t.Errorf("expect sq condition LastProbeTime %v but got %v", expectNewSqCondition.LastProbeTime, actualNewSqCondition.LastProbeTime)
}
if actualNewSqCondition.LastActionTransitionTime.IsZero() != expectNewSqCondition.LastActionTransitionTime.IsZero() {
t.Errorf("expect sq condition LastActionTransitionTime IsZero %v but got %v", expectNewSqCondition.LastActionTransitionTime.IsZero(), actualNewSqCondition.LastActionTransitionTime.IsZero())
}
break
}
}
if !exist {
t.Errorf("expect sq condition %s exist, but actually not", expectNewSqCondition.Name)
}
}
}
}

View File

@ -225,7 +225,6 @@ func (r *GameServerSetReconciler) Reconcile(ctx context.Context, req ctrl.Reques
return reconcile.Result{}, nil
}
// TODO sync PodProbeMarker
err = gsm.SyncPodProbeMarker()
if err != nil {
klog.Errorf("GameServerSet %s failed to synchronize PodProbeMarker in %s,because of %s.", namespacedName.Name, namespacedName.Namespace, err.Error())
@ -267,10 +266,10 @@ func (r *GameServerSetReconciler) initAsts(gss *gamekruiseiov1alpha1.GameServerS
ors = append(ors, or)
asts.SetOwnerReferences(ors)
// set label
astsLabels := make(map[string]string)
astsLabels[gamekruiseiov1alpha1.AstsHashKey] = util.GetAstsHash(gss)
asts.SetLabels(astsLabels)
// set annotations
astsAns := make(map[string]string)
astsAns[gamekruiseiov1alpha1.AstsHashKey] = util.GetAstsHash(gss)
asts.SetAnnotations(astsAns)
// set label selector
asts.Spec.Selector = &metav1.LabelSelector{

View File

@ -18,10 +18,13 @@ package gameserverset
import (
"context"
kruiseV1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
kruiseV1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
gameKruiseV1alpha1 "github.com/openkruise/kruise-game/apis/v1alpha1"
"github.com/openkruise/kruise-game/pkg/util"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/klog/v2"
@ -58,19 +61,15 @@ func NewGameServerSetManager(gss *gameKruiseV1alpha1.GameServerSet, asts *kruise
func (manager *GameServerSetManager) IsNeedToScale() bool {
gss := manager.gameServerSet
asts := manager.asts
gsList := manager.podList
currentReplicas := len(gsList)
workloadReplicas := int(*asts.Spec.Replicas)
expectedReplicas := int(*gss.Spec.Replicas)
// workload is reconciling its replicas, don't interrupt
if currentReplicas != workloadReplicas {
if asts.Status.Replicas != *asts.Spec.Replicas {
return false
}
// no need to scale
return !(expectedReplicas == currentReplicas && util.IsSliceEqual(util.StringToIntSlice(gss.GetAnnotations()[gameKruiseV1alpha1.GameServerSetReserveIdsKey], ","), gss.Spec.ReserveGameServerIds))
return !(*gss.Spec.Replicas == *asts.Spec.Replicas &&
util.IsSliceEqual(util.StringToIntSlice(gss.GetAnnotations()[gameKruiseV1alpha1.GameServerSetReserveIdsKey], ","), gss.Spec.ReserveGameServerIds))
}
func (manager *GameServerSetManager) GameServerScale() error {
@ -84,7 +83,7 @@ func (manager *GameServerSetManager) GameServerScale() error {
expectedReplicas := int(*gss.Spec.Replicas)
as := gss.GetAnnotations()
reserveIds := util.StringToIntSlice(as[gameKruiseV1alpha1.GameServerSetReserveIdsKey], ",")
notExistIds := util.StringToIntSlice(as[gameKruiseV1alpha1.GameServerSetNotExistIdsKey], ",")
notExistIds := util.GetSliceInANotInB(asts.Spec.ReserveOrdinals, reserveIds)
gssReserveIds := gss.Spec.ReserveGameServerIds
klog.Infof("GameServers %s/%s already has %d replicas, expect to have %d replicas.", gss.GetNamespace(), gss.GetName(), currentReplicas, expectedReplicas)
@ -104,7 +103,6 @@ func (manager *GameServerSetManager) GameServerScale() error {
gssAnnotations := make(map[string]string)
gssAnnotations[gameKruiseV1alpha1.GameServerSetReserveIdsKey] = util.IntSliceToString(gssReserveIds, ",")
gssAnnotations[gameKruiseV1alpha1.GameServerSetNotExistIdsKey] = util.IntSliceToString(newNotExistIds, ",")
patchGss := map[string]interface{}{"metadata": map[string]map[string]string{"annotations": gssAnnotations}}
patchGssBytes, _ := json.Marshal(patchGss)
err = c.Patch(ctx, gss, client.RawPatch(types.MergePatchType, patchGssBytes))
@ -182,7 +180,7 @@ func computeToScaleGs(gssReserveIds, reserveIds, notExistIds []int, expectedRepl
}
func (manager *GameServerSetManager) IsNeedToUpdateWorkload() bool {
return manager.asts.GetLabels()[gameKruiseV1alpha1.AstsHashKey] != util.GetAstsHash(manager.gameServerSet)
return manager.asts.GetAnnotations()[gameKruiseV1alpha1.AstsHashKey] != util.GetAstsHash(manager.gameServerSet)
}
func (manager *GameServerSetManager) UpdateWorkload() error {
@ -191,16 +189,94 @@ func (manager *GameServerSetManager) UpdateWorkload() error {
// sync with Advanced StatefulSet
asts = util.GetNewAstsFromGss(gss, asts)
astsLabels := asts.GetLabels()
astsLabels[gameKruiseV1alpha1.AstsHashKey] = util.GetAstsHash(manager.gameServerSet)
asts.SetLabels(astsLabels)
astsAns := asts.GetAnnotations()
astsAns[gameKruiseV1alpha1.AstsHashKey] = util.GetAstsHash(manager.gameServerSet)
asts.SetAnnotations(astsAns)
return manager.client.Update(context.Background(), asts)
}
func (manager *GameServerSetManager) SyncPodProbeMarker() error {
gss := manager.gameServerSet
sqs := gss.Spec.ServiceQualities
c := manager.client
ctx := context.Background()
// get ppm
ppm := &kruiseV1alpha1.PodProbeMarker{}
err := c.Get(ctx, types.NamespacedName{
Namespace: gss.GetNamespace(),
Name: gss.GetName(),
}, ppm)
if err != nil {
if errors.IsNotFound(err) {
if sqs == nil {
return nil
}
// create ppm
return c.Create(ctx, createPpm(gss))
}
return err
}
// delete ppm
if sqs == nil {
return c.Delete(ctx, ppm)
}
// update ppm
if util.GetHash(gss.Spec.ServiceQualities) != ppm.GetAnnotations()[gameKruiseV1alpha1.PpmHashKey] {
ppm.Spec.Probes = constructProbes(gss)
return c.Update(ctx, ppm)
}
return nil
}
func constructProbes(gss *gameKruiseV1alpha1.GameServerSet) []kruiseV1alpha1.PodContainerProbe {
var probes []kruiseV1alpha1.PodContainerProbe
for _, sq := range gss.Spec.ServiceQualities {
probe := kruiseV1alpha1.PodContainerProbe{
Name: sq.Name,
ContainerName: sq.ContainerName,
Probe: kruiseV1alpha1.ContainerProbeSpec{
Probe: sq.Probe,
},
PodConditionType: util.AddPrefixGameKruise(sq.Name),
}
probes = append(probes, probe)
}
return probes
}
func createPpm(gss *gameKruiseV1alpha1.GameServerSet) *kruiseV1alpha1.PodProbeMarker {
// set owner reference
ors := make([]metav1.OwnerReference, 0)
or := metav1.OwnerReference{
APIVersion: gss.APIVersion,
Kind: gss.Kind,
Name: gss.GetName(),
UID: gss.GetUID(),
Controller: pointer.BoolPtr(true),
BlockOwnerDeletion: pointer.BoolPtr(true),
}
ors = append(ors, or)
return &kruiseV1alpha1.PodProbeMarker{
ObjectMeta: metav1.ObjectMeta{
Name: gss.GetName(),
Namespace: gss.GetNamespace(),
Annotations: map[string]string{
gameKruiseV1alpha1.PpmHashKey: util.GetHash(gss.Spec.ServiceQualities),
},
OwnerReferences: ors,
},
Spec: kruiseV1alpha1.PodProbeMarkerSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{gameKruiseV1alpha1.GameServerOwnerGssKey: gss.GetName()},
},
Probes: constructProbes(gss),
},
}
}
func (manager *GameServerSetManager) SyncStatus() error {
gss := manager.gameServerSet
asts := manager.asts

View File

@ -162,3 +162,11 @@ func GetAstsHash(gss *gameKruiseV1alpha1.GameServerSet) string {
Template: gss.Spec.GameServerTemplate,
})
}
func AddPrefixGameKruise(s string) string {
return "game.kruise.io/" + s
}
func RemovePrefixGameKruise(s string) string {
return strings.TrimPrefix(s, "game.kruise.io/")
}

View File

@ -108,3 +108,47 @@ func TestDeleteSequenceGs(t *testing.T) {
}
}
}
func TestAddPrefixGameKruise(t *testing.T) {
tests := []struct {
s string
result string
}{
{
s: "healthy",
result: "game.kruise.io/healthy",
},
}
for _, test := range tests {
actual := AddPrefixGameKruise(test.s)
expect := test.result
if expect != actual {
t.Errorf("expect %v but got %v", expect, actual)
}
}
}
func TestRemovePrefixGameKruise(t *testing.T) {
tests := []struct {
s string
result string
}{
{
s: "game.kruise.io/healthy",
result: "healthy",
},
{
s: "game/healthy",
result: "game/healthy",
},
}
for _, test := range tests {
actual := RemovePrefixGameKruise(test.s)
expect := test.result
if expect != actual {
t.Errorf("expect %v but got %v", expect, actual)
}
}
}

33
pkg/util/pod.go Normal file
View File

@ -0,0 +1,33 @@
/*
Copyright 2022 The Kruise Authors.
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.
*/
package util
import corev1 "k8s.io/api/core/v1"
// GetPodConditionFromList extracts the provided condition from the given list of condition and
// returns the index of the condition and the condition. Returns -1 and nil if the condition is not present.
func GetPodConditionFromList(conditions []corev1.PodCondition, conditionType corev1.PodConditionType) (int, *corev1.PodCondition) {
if conditions == nil {
return -1, nil
}
for i := range conditions {
if conditions[i].Type == conditionType {
return i, &conditions[i]
}
}
return -1, nil
}

61
pkg/util/pod_test.go Normal file
View File

@ -0,0 +1,61 @@
/*
Copyright 2022 The Kruise Authors.
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.
*/
package util
import (
corev1 "k8s.io/api/core/v1"
"reflect"
"testing"
)
func TestGetPodConditionFromList(t *testing.T) {
tests := []struct {
podConditions []corev1.PodCondition
conditionType corev1.PodConditionType
index int
podCondition *corev1.PodCondition
}{
{
podConditions: []corev1.PodCondition{
{
Type: "game.kruise.io/healthy",
Status: corev1.ConditionTrue,
},
{
Type: corev1.PodReady,
Status: corev1.ConditionFalse,
},
},
conditionType: corev1.PodReady,
index: 1,
podCondition: &corev1.PodCondition{
Type: corev1.PodReady,
Status: corev1.ConditionFalse,
},
},
}
for _, test := range tests {
actualIndex, actualPodCondition := GetPodConditionFromList(test.podConditions, test.conditionType)
if actualIndex != test.index {
t.Errorf("expect to get index %v but got %v", test.index, actualIndex)
}
if !reflect.DeepEqual(*test.podCondition, *actualPodCondition) {
t.Errorf("expect to get condition %v but got %v", *test.podCondition, *actualPodCondition)
}
}
}

View File

@ -57,6 +57,7 @@ func init() {
// +kubebuilder:rbac:groups=apps.kruise.io,resources=statefulsets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=apps.kruise.io,resources=statefulsets/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=apps.kruise.io,resources=podprobemarkers,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=pods/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations,verbs=create;get;list;watch;update;patch

View File

@ -10,6 +10,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
@ -57,6 +58,42 @@ func (f *Framework) DeployGameServerSet() (*gamekruiseiov1alpha1.GameServerSet,
return f.client.CreateGameServerSet(gss)
}
func (f *Framework) DeployGssWithServiceQualities() (*gamekruiseiov1alpha1.GameServerSet, error) {
gss := f.client.DefaultGameServerSet()
up := intstr.FromInt(20)
dp := intstr.FromInt(10)
sqs := []gamekruiseiov1alpha1.ServiceQuality{
{
Name: "healthy",
ContainerName: client.GameContainerName,
Probe: corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Command: []string{"/bin/sh", "-c", "ls /"},
},
},
},
Permanent: false,
ServiceQualityAction: []gamekruiseiov1alpha1.ServiceQualityAction{
{
State: true,
GameServerSpec: gamekruiseiov1alpha1.GameServerSpec{
UpdatePriority: &up,
},
},
{
State: false,
GameServerSpec: gamekruiseiov1alpha1.GameServerSpec{
DeletionPriority: &dp,
},
},
},
},
}
gss.Spec.ServiceQualities = sqs
return f.client.CreateGameServerSet(gss)
}
func (f *Framework) GameServerScale(gss *gamekruiseiov1alpha1.GameServerSet, desireNum int, reserveGsId *int) (*gamekruiseiov1alpha1.GameServerSet, error) {
// TODO: change patch type
newReserves := gss.Spec.ReserveGameServerIds
@ -215,3 +252,18 @@ func (f *Framework) WaitForGsDeletionPriorityUpdated(gsName string, deletionPrio
return false, nil
})
}
func (f *Framework) WaitForGsUpdatePriorityUpdated(gsName string, updatePriority string) error {
return wait.PollImmediate(5*time.Second, 1*time.Minute,
func() (done bool, err error) {
pod, err := f.client.GetPod(gsName)
if err != nil {
return false, err
}
currentPriority := pod.GetLabels()[gamekruiseiov1alpha1.GameServerUpdatePriorityKey]
if currentPriority == updatePriority {
return true, nil
}
return false, nil
})
}

View File

@ -74,5 +74,22 @@ func RunTestCases(f *framework.Framework) {
err = f.WaitForUpdated(gss, client.GameContainerName, "nginx:latest")
gomega.Expect(err).To(gomega.BeNil())
})
ginkgo.It("service qualities", func() {
// deploy
gss, err := f.DeployGssWithServiceQualities()
gomega.Expect(err).To(gomega.BeNil())
err = f.ExpectGssCorrect(gss, []int{0, 1, 2})
gomega.Expect(err).To(gomega.BeNil())
err = f.WaitForGsUpdatePriorityUpdated(gss.GetName()+"-0", "20")
gomega.Expect(err).To(gomega.BeNil())
err = f.WaitForGsUpdatePriorityUpdated(gss.GetName()+"-1", "20")
gomega.Expect(err).To(gomega.BeNil())
err = f.WaitForGsUpdatePriorityUpdated(gss.GetName()+"-2", "20")
gomega.Expect(err).To(gomega.BeNil())
})
})
}