cockroach.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. from pathlib import Path
  10. from kubernetes.client import (
  11. V1ConfigMap,
  12. V1ConfigMapVolumeSource,
  13. V1Container,
  14. V1ContainerPort,
  15. V1LabelSelector,
  16. V1ObjectMeta,
  17. V1PersistentVolumeClaim,
  18. V1PersistentVolumeClaimSpec,
  19. V1PodSpec,
  20. V1PodTemplateSpec,
  21. V1ResourceRequirements,
  22. V1Service,
  23. V1ServicePort,
  24. V1ServiceSpec,
  25. V1StatefulSet,
  26. V1StatefulSetSpec,
  27. V1Volume,
  28. V1VolumeMount,
  29. )
  30. from materialize import MZ_ROOT
  31. from materialize.cloudtest import DEFAULT_K8S_NAMESPACE
  32. from materialize.cloudtest.k8s.api.k8s_config_map import K8sConfigMap
  33. from materialize.cloudtest.k8s.api.k8s_resource import K8sResource
  34. from materialize.cloudtest.k8s.api.k8s_service import K8sService
  35. from materialize.cloudtest.k8s.api.k8s_stateful_set import K8sStatefulSet
  36. from materialize.mzcompose.services.cockroach import Cockroach
  37. class CockroachConfigMap(K8sConfigMap):
  38. def __init__(self, namespace: str, path_to_setup_script: Path):
  39. super().__init__(namespace)
  40. self.config_map = V1ConfigMap(
  41. metadata=V1ObjectMeta(
  42. name="cockroach-init",
  43. ),
  44. data={
  45. "setup_materialize.sql": path_to_setup_script.read_text(),
  46. },
  47. )
  48. class CockroachService(K8sService):
  49. def __init__(self, namespace: str):
  50. super().__init__(namespace)
  51. service_port = V1ServicePort(name="sql", port=26257)
  52. self.service = V1Service(
  53. api_version="v1",
  54. kind="Service",
  55. metadata=V1ObjectMeta(name="cockroach", labels={"app": "cockroach"}),
  56. spec=V1ServiceSpec(
  57. type="NodePort", ports=[service_port], selector={"app": "cockroach"}
  58. ),
  59. )
  60. class CockroachStatefulSet(K8sStatefulSet):
  61. def __init__(
  62. self, namespace: str = DEFAULT_K8S_NAMESPACE, apply_node_selectors: bool = False
  63. ):
  64. self.apply_node_selectors = apply_node_selectors
  65. super().__init__(namespace)
  66. def generate_stateful_set(self) -> V1StatefulSet:
  67. metadata = V1ObjectMeta(name="cockroach", labels={"app": "cockroach"})
  68. label_selector = V1LabelSelector(match_labels={"app": "cockroach"})
  69. ports = [V1ContainerPort(container_port=26257, name="sql")]
  70. volume_mounts = [
  71. V1VolumeMount(name="data", mount_path="/cockroach/cockroach-data"),
  72. V1VolumeMount(
  73. name="cockroach-init", mount_path="/docker-entrypoint-initdb.d"
  74. ),
  75. ]
  76. volume_config = V1ConfigMapVolumeSource(
  77. name="cockroach-init",
  78. )
  79. volumes = [V1Volume(name="cockroach-init", config_map=volume_config)]
  80. container = V1Container(
  81. name="cockroach",
  82. image=f"cockroachdb/cockroach:{Cockroach.DEFAULT_COCKROACH_TAG}",
  83. args=["start-single-node", "--insecure"],
  84. ports=ports,
  85. volume_mounts=volume_mounts,
  86. )
  87. node_selector = None
  88. if self.apply_node_selectors:
  89. node_selector = {"supporting-services": "true"}
  90. pod_spec = V1PodSpec(
  91. containers=[container],
  92. volumes=volumes,
  93. node_selector=node_selector,
  94. )
  95. template_spec = V1PodTemplateSpec(metadata=metadata, spec=pod_spec)
  96. claim_templates = [
  97. V1PersistentVolumeClaim(
  98. metadata=V1ObjectMeta(name="data"),
  99. spec=V1PersistentVolumeClaimSpec(
  100. access_modes=["ReadWriteOnce"],
  101. resources=V1ResourceRequirements(requests={"storage": "1Gi"}),
  102. ),
  103. )
  104. ]
  105. return V1StatefulSet(
  106. api_version="apps/v1",
  107. kind="StatefulSet",
  108. metadata=metadata,
  109. spec=V1StatefulSetSpec(
  110. service_name="cockroach",
  111. replicas=1,
  112. selector=label_selector,
  113. template=template_spec,
  114. volume_claim_templates=claim_templates,
  115. ),
  116. )
  117. def cockroach_resources(
  118. namespace: str = DEFAULT_K8S_NAMESPACE,
  119. path_to_setup_script: Path = MZ_ROOT
  120. / "misc"
  121. / "cockroach"
  122. / "setup_materialize.sql",
  123. apply_node_selectors: bool = False,
  124. ) -> list[K8sResource]:
  125. return [
  126. CockroachConfigMap(namespace, path_to_setup_script),
  127. CockroachService(namespace),
  128. CockroachStatefulSet(namespace, apply_node_selectors),
  129. ]