Skip to content

Commit

Permalink
feat: support the override of agones health check in proxy and minecr…
Browse files Browse the repository at this point in the history
…aft template

feat: add health docs to podOverride
  • Loading branch information
HookWoods committed Sep 3, 2024
1 parent ee0108a commit 68acf16
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 16 deletions.
25 changes: 25 additions & 0 deletions docs/src/next/guide/recipes/overriding-pod-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,31 @@ spec:
effect: "NoSchedule" // [!code focus]
```

## Customizing agones health check

Agones uses a health check to determine if a server is ready and healthy.
You may want to customize the health check to better suit your needs
(e.g. your server takes 1 minute to start, you may want to increase the `initial_delay_seconds` to 60).

```yaml
apiVersion: shulkermc.io/v1alpha1
kind: MinecraftServerFleet
metadata:
name: my-server
spec:
clusterRef:
name: my-cluster
replicas: 1
template:
spec: // [!code focus]
podOverrides: // [!code focus]
health: // [!code focus]
disabled: false // [!code focus]
initial_delay_seconds: 30 // [!code focus]
period_seconds: 15 // [!code focus]
failureThreshold: 5 // [!code focus]
```

## Mounting volumes <Badge type="tip" text="servers" />

Additional volumes can be injected to the `MinecraftServer`'s
Expand Down
24 changes: 24 additions & 0 deletions kube/helm/templates/crds/shulkermc.io_minecraftserverfleets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,30 @@ spec:
type: object
nullable: true
type: array
health:
description: Overrides Agones Health checks
nullable: true
properties:
disabled:
description: Specify whether the health check should be disabled.
nullable: true
type: boolean
failureThreshold:
description: Specify how much health failure is tolerated before the GameServer is considered unhealthy.
format: int32
nullable: true
type: integer
initialDelaySeconds:
description: Specify the initial delay in seconds before the first health check is performed.
format: int32
nullable: true
type: integer
periodSeconds:
description: Specify the period in seconds between health checks.
format: int32
nullable: true
type: integer
type: object
image:
description: Image to use as replacement for the built-in one
nullable: true
Expand Down
24 changes: 24 additions & 0 deletions kube/helm/templates/crds/shulkermc.io_minecraftservers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,30 @@ spec:
type: object
nullable: true
type: array
health:
description: Overrides Agones Health checks
nullable: true
properties:
disabled:
description: Specify whether the health check should be disabled.
nullable: true
type: boolean
failureThreshold:
description: Specify how much health failure is tolerated before the GameServer is considered unhealthy.
format: int32
nullable: true
type: integer
initialDelaySeconds:
description: Specify the initial delay in seconds before the first health check is performed.
format: int32
nullable: true
type: integer
periodSeconds:
description: Specify the period in seconds between health checks.
format: int32
nullable: true
type: integer
type: object
image:
description: Image to use as replacement for the built-in one
nullable: true
Expand Down
24 changes: 24 additions & 0 deletions kube/helm/templates/crds/shulkermc.io_proxyfleets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,30 @@ spec:
type: object
nullable: true
type: array
health:
description: Overrides Agones Health checks
nullable: true
properties:
disabled:
description: Specify whether the health check should be disabled.
nullable: true
type: boolean
failureThreshold:
description: Specify how much health failure is tolerated before the GameServer is considered unhealthy.
format: int32
nullable: true
type: integer
initialDelaySeconds:
description: Specify the initial delay in seconds before the first health check is performed.
format: int32
nullable: true
type: integer
periodSeconds:
description: Specify the period in seconds between health checks.
format: int32
nullable: true
type: integer
type: object
image:
description: Image to use as replacement for the built-in one
nullable: true
Expand Down
7 changes: 7 additions & 0 deletions packages/google-agones-crds/src/v1/game_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,19 @@ pub struct GameServerPortSpec {
#[derive(Deserialize, Serialize, Clone, Debug, JsonSchema, Default)]
#[serde(rename_all = "camelCase")]
pub struct GameServerHealthSpec {
/// Specify whether the health check should be disabled.
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<bool>,

/// Specify the period in seconds between health checks.
#[serde(skip_serializing_if = "Option::is_none")]
pub period_seconds: Option<i32>,

/// Specify how much health failure is tolerated before the GameServer is considered unhealthy.
#[serde(skip_serializing_if = "Option::is_none")]
pub failure_threshold: Option<i32>,

/// Specify the initial delay in seconds before the first health check is performed.
#[serde(skip_serializing_if = "Option::is_none")]
pub initial_delay_seconds: Option<i32>,
}
Expand Down
8 changes: 6 additions & 2 deletions packages/shulker-crds/src/v1alpha1/minecraft_server.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::collections::BTreeMap;

use super::minecraft_cluster::MinecraftClusterRef;
use google_agones_crds::v1::game_server::GameServerHealthSpec;
use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition;
use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum::{Display, IntoStaticStr};

use super::minecraft_cluster::MinecraftClusterRef;

use crate::{condition::HasConditions, resourceref::ResourceRefSpec, schemas::ImageOverrideSpec};

#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema, Default)]
Expand Down Expand Up @@ -206,6 +206,10 @@ pub struct MinecraftServerPodOverridesSpec {
/// Extra ports to add to the created `Pod`'s main container
#[serde(skip_serializing_if = "Option::is_none")]
pub ports: Option<Vec<k8s_openapi::api::core::v1::ContainerPort>>,

/// Overrides Agones Health checks
#[serde(skip_serializing_if = "Option::is_none")]
pub health: Option<GameServerHealthSpec>,
}

/// The status object of `MinecraftServer`
Expand Down
8 changes: 6 additions & 2 deletions packages/shulker-crds/src/v1alpha1/proxy_fleet.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::collections::BTreeMap;

use super::minecraft_cluster::MinecraftClusterRef;
use google_agones_crds::v1::game_server::GameServerHealthSpec;
use k8s_openapi::apimachinery::pkg::apis::meta::v1::Condition;
use kube::CustomResource;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum::{Display, IntoStaticStr};

use super::minecraft_cluster::MinecraftClusterRef;

use crate::{
condition::HasConditions,
resourceref::ResourceRefSpec,
Expand Down Expand Up @@ -221,6 +221,10 @@ pub struct ProxyFleetTemplatePodOverridesSpec {
/// Extra ports to add to the created `Pod`'s main container
#[serde(skip_serializing_if = "Option::is_none")]
pub ports: Option<Vec<k8s_openapi::api::core::v1::ContainerPort>>,

/// Overrides Agones Health checks
#[serde(skip_serializing_if = "Option::is_none")]
pub health: Option<GameServerHealthSpec>,
}

#[derive(Deserialize, Serialize, Clone, Debug, Default, JsonSchema)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ lazy_static! {
volume_mounts: None,
volumes: None,
ports: None,
health: None,
})
},
status: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,42 @@ impl<'a> GameServerBuilder {
) -> Result<GameServerSpec, anyhow::Error> {
let pod_template_spec =
Self::get_pod_template_spec(resourceref_resolver, context, minecraft_server).await?;
let spec = &minecraft_server.spec;

// Default health configuration
let default_health = GameServerHealthSpec {
disabled: Some(false),
initial_delay_seconds: Some(30),
period_seconds: Some(15),
failure_threshold: Some(5),
};

// Initialize health_spec with the default values
let mut health_spec = default_health.clone();

// Check if pod_overrides is present
if let Some(pod_overrides) = &spec.pod_overrides {
// Check if health is present within pod_overrides
if let Some(health) = &pod_overrides.health {
// Override the defaults with the values from health if they are present
health_spec.disabled = health.disabled.or(default_health.disabled);
health_spec.initial_delay_seconds = health
.initial_delay_seconds
.or(default_health.initial_delay_seconds);
health_spec.period_seconds =
health.period_seconds.or(default_health.period_seconds);
health_spec.failure_threshold = health
.failure_threshold
.or(default_health.failure_threshold);
}
}

let game_server_spec = GameServerSpec {
ports: Some(vec![]),
eviction: Some(GameServerEvictionSpec {
safe: "OnUpgrade".to_string(),
}),
health: Some(GameServerHealthSpec {
disabled: Some(false),
initial_delay_seconds: Some(30),
period_seconds: Some(15),
failure_threshold: Some(5),
}),
health: Some(health_spec),
template: pod_template_spec,
};

Expand Down Expand Up @@ -628,6 +652,7 @@ impl<'a> GameServerBuilder {

#[cfg(test)]
mod tests {
use google_agones_crds::v1::game_server::GameServerHealthSpec;
use k8s_openapi::api::core::v1::{
ContainerPort, EmptyDirVolumeSource, LocalObjectReference, Volume, VolumeMount,
};
Expand Down Expand Up @@ -1073,6 +1098,43 @@ mod tests {
);
}

#[tokio::test]
async fn get_health_settings_from_pod_overrides() {
// G
let client = create_client_mock();
let resourceref_resolver = ResourceRefResolver::new(client);
let mut server = TEST_SERVER.clone();
server.spec.pod_overrides.as_mut().unwrap().health = Some(GameServerHealthSpec {
disabled: Some(true),
initial_delay_seconds: Some(10),
period_seconds: Some(20),
failure_threshold: Some(3),
});
let context = super::GameServerBuilderContext {
cluster: &TEST_CLUSTER,
agent_config: &AgentConfig {
maven_repository: constants::SHULKER_PLUGIN_REPOSITORY.to_string(),
version: constants::SHULKER_PLUGIN_VERSION.to_string(),
},
};

// W
let game_server_spec = super::GameServerBuilder::get_game_server_spec(
&resourceref_resolver,
&context,
&server,
)
.await
.unwrap();

// T
let health_spec = game_server_spec.health.unwrap();
assert_eq!(health_spec.disabled, Some(true));
assert_eq!(health_spec.initial_delay_seconds, Some(10));
assert_eq!(health_spec.period_seconds, Some(20));
assert_eq!(health_spec.failure_threshold, Some(3));
}

#[tokio::test]
async fn get_env_merges_env_overrides() {
// G
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ lazy_static! {
volume_mounts: None,
volumes: None,
ports: None,
health: None,
})
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ lazy_static! {
volume_mounts: None,
volumes: None,
ports: None,
health: None,
})
},
},
Expand Down
Loading

0 comments on commit 68acf16

Please sign in to comment.