in gamelift-daemon/src/main.py [0:0]
def initialize_game_server(GameServerGroupName: str, GameServerId: str, InstanceId: str):
"""This method registers the instance as a game server with Gamelift FleetIQ using the instance's Id as game server name.
After registering the instance, it looks at result of DescribeAutoscalingInstances to see whether the instance is HEALTHY.
When HEALTHY, the instance is CLAIMED and its status is changed to UTILIZED. Finally, the taint gamelift.aws/status:ACTIVE,NoExecute
is added to the node. Agones game servers need to have a toleration for this taint before they can run on this instance."""
try:
# Register game server instance
print('Registering game server', flush=True)
gamelift.register_game_server(
GameServerGroupName=GameServerGroupName,
GameServerId=GameServerId,
InstanceId=InstanceId
)
except gamelift.exceptions.ConflictException as error:
print('The game server is already registered', flush=True)
pass
# Update the game server status to healthy
# TODO(jicowan@amazon.com) Change this to use the new FleetIQ API DescribeGameServerInstances
# TODO(jicowan@amazon.com) Consider using a decorator and backoff library to implement the backoff
backoff = random.randint(1,5)
while is_healthy(InstanceId) != 'HEALTHY':
print(f'Instance is not healthy, re-trying in {backoff}', flush=True)
sleep(backoff)
print('Updating game server health', flush=True)
gamelift.update_game_server(
GameServerGroupName=GameServerGroupName,
GameServerId=GameServerId,
HealthCheck='HEALTHY'
)
# Claim the game server
print('Claiming game server', flush=True)
try:
gamelift.claim_game_server(
GameServerGroupName=GameServerGroupName,
GameServerId=GameServerId
)
except gamelift.exceptions.ConflictException as error:
print('The instance has already been claimed', flush=True)
# Update game server status
print('Changing status to utilized', flush=True)
gamelift.update_game_server(
GameServerGroupName=GameServerGroupName,
GameServerId=GameServerId,
UtilizationStatus='UTILIZED'
)
# Adding taint to node
# TODO(jicowan@amazon.com) Make tainting a node a separate method call because it's used multiple times.
taint = {
"key": "gamelift.status/active",
"value": "true",
"effect": "NoExecute"
}
try:
node = core_v1_client.read_node(ec2_metadata.private_hostname)
except ApiException as e:
print(f'Exception when calling CoreV1Api->read_node: {e}\n', flush=True)
taints = node.spec.taints
taints.append(taint)
taint_body = {
"spec": {
"taints": taints
}
}
try:
core_v1_client.patch_node(ec2_metadata.private_hostname, taint_body)
print(f'Node {InstanceId} has been tainted', flush=True)
except ApiException as e:
print(f'The node {InstanceId} has already been tainted', flush=True)