Skip to content

Commit

Permalink
Fix Kubernetes engine
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Gu <[email protected]>
  • Loading branch information
tylergu committed Oct 7, 2024
1 parent 73ad3d9 commit f6eda21
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 12 deletions.
10 changes: 8 additions & 2 deletions acto/kubectl_client/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,26 @@ def install(
release_name: str,
chart: str,
namespace: str,
namespace_existed: Optional[bool] = None,
repo: Optional[str] = None,
version: Optional[str] = None,
args: Optional[list] = None,
) -> subprocess.CompletedProcess:
"""Installs a helm chart"""
"""Installs a helm chart. It uses the --wait flag to wait for the deployment to be ready"""
cmd = [
"install",
release_name,
chart,
"--namespace",
namespace,
"--create-namespace",
"--wait",
]
if namespace_existed is False:
cmd.append("--create-namespace")
if repo:
cmd.extend(["--repo", repo])
if version:
cmd.extend(["--version", version])
if args:
cmd.extend(args)
return self.helm(cmd)
5 changes: 5 additions & 0 deletions acto/kubernetes_engine/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,8 @@ def get_node_list(self, name: str):
# no nodes can be found, returning an empty array
return []
return p.stdout.strip().split("\n")

@staticmethod
def cluster_name(acto_namespace: int, worker_id: int) -> str:
"""Helper function to generate cluster name"""
return f"acto-{acto_namespace}-cluster-{worker_id}"
2 changes: 1 addition & 1 deletion acto/kubernetes_engine/minikube.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def create_cluster(self, name: str, kubeconfig: str):
else:
raise RuntimeError("Missing kubeconfig for minikube create")

cmd.extend(["--nodes", str(self.num_nodes)])
cmd.extend(["--nodes", str(self.num_nodes + 1)])

if self._k8s_version != "":
cmd.extend(["--kubernetes-version", str(self._k8s_version)])
Expand Down
76 changes: 69 additions & 7 deletions acto/lib/operator_config.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
from typing import Optional

import pydantic
from typing_extensions import Self

from acto.input.constraint import XorCondition

DELEGATED_NAMESPACE = "__DELEGATED__"


class ApplyStep(pydantic.BaseModel, extra="forbid"):
"""Configuration for each step of kubectl apply"""

file: str = pydantic.Field(
description="Path to the file for kubectl apply")
file: str = pydantic.Field(description="Path to the file for kubectl apply")
operator: bool = pydantic.Field(
description="If the file contains the operator deployment",
default=False,
Expand All @@ -35,20 +37,73 @@ class WaitStep(pydantic.BaseModel, extra="forbid"):
)


class HelmInstallStep(pydantic.BaseModel, extra="forbid"):
"""Configuration for each step of helm install"""

release_name: str = pydantic.Field(
description="Name of the release for helm install",
default="operator-release",
)
chart: str = pydantic.Field(
description="Path to the chart for helm install"
)
namespace: Optional[str] = pydantic.Field(
description="Namespace for installing the chart. If not specified, "
+ "use the namespace in the chart or Acto namespace. "
+ "If set to null, use the namespace in the chart",
default=DELEGATED_NAMESPACE,
)
repo: Optional[str] = pydantic.Field(
description="Name of the helm repository", default=None
)
version: Optional[str] = pydantic.Field(
description="Version of the helm chart", default=None
)
operator: bool = pydantic.Field(
description="If the file contains the operator deployment",
default=False,
)
operator_deployment_name: Optional[str] = pydantic.Field(
description="The deployment name of the operator in the operator pod, "
"required if there are multiple deployments in the operator pod",
default=None,
)
operator_container_name: Optional[str] = pydantic.Field(
description="The container name of the operator in the operator pod, "
"required if there are multiple containers in the operator pod",
default=None,
)

@pydantic.model_validator(mode="after")
def check_operator_helm_install(self) -> Self:
"""Check if the operator helm install is valid"""
if self.operator:
if (
not self.operator_deployment_name
or not self.operator_container_name
):
raise ValueError(
"operator_deployment_name and operator_container_name "
+ "are required for operator helm install for operator"
)
return self


class DeployStep(pydantic.BaseModel, extra="forbid"):
"""A step of deploying a resource"""

apply: ApplyStep = pydantic.Field(
apply: Optional[ApplyStep] = pydantic.Field(
description="Configuration for each step of kubectl apply", default=None
)
wait: WaitStep = pydantic.Field(
wait: Optional[WaitStep] = pydantic.Field(
description="Configuration for each step of waiting for the operator",
default=None,
)
helm_install: Optional[HelmInstallStep] = pydantic.Field(
description="Configuration for each step of helm install", default=None
)

# TODO: Add support for helm and kustomize
# helm: str = pydantic.Field(
# description="Path to the file for helm install")
# TODO: Add support and kustomize
# kustomize: str = pydantic.Field(
# description="Path to the file for kustomize build")

Expand Down Expand Up @@ -130,6 +185,10 @@ class OperatorConfig(pydantic.BaseModel, extra="forbid"):
default=None,
description="Name of the CRD, required if there are multiple CRDs",
)
crd_version: Optional[str] = pydantic.Field(
default=None,
description="Version of the CRD, required if there are multiple CRD versions",
)
example_dir: Optional[str] = pydantic.Field(
default=None, description="Path to the example dir"
)
Expand All @@ -139,6 +198,9 @@ class OperatorConfig(pydantic.BaseModel, extra="forbid"):
focus_fields: Optional[list[list[str]]] = pydantic.Field(
default=None, description="List of focus fields"
)
constraints: Optional[list[XorCondition]] = pydantic.Field(
default=None, description="List of constraints"
)


if __name__ == "__main__":
Expand Down
6 changes: 4 additions & 2 deletions test/integration_tests/test_kubernetes_engines.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import pytest

# from acto.kubernetes_engine.base import KubernetesEngine
from acto.kubernetes_engine.base import KubernetesEngine
from acto.kubernetes_engine.kind import Kind
from acto.kubernetes_engine.minikube import Minikube

testcases = [("kind", 3, "v1.27.3")]
testcases = [("kind", 4, "v1.27.3")]


@pytest.mark.kubernetes_engine
Expand All @@ -18,6 +19,7 @@ def test_kubernetes_engines(cluster_type: str, num_nodes, version):
config_path = os.path.join(os.path.expanduser("~"), ".kube/test-config")
name = "test-cluster"

cluster_instance: KubernetesEngine
if cluster_type == "kind":
cluster_instance = Kind(
acto_namespace=0, num_nodes=num_nodes, version=version
Expand All @@ -34,7 +36,7 @@ def test_kubernetes_engines(cluster_type: str, num_nodes, version):
cluster_instance.create_cluster(name, config_path)

node_list = cluster_instance.get_node_list(name)
assert len(node_list) == num_nodes
assert len(node_list) == num_nodes + 1

cluster_instance.delete_cluster(name, config_path)
with pytest.raises(RuntimeError):
Expand Down

0 comments on commit f6eda21

Please sign in to comment.