forked from cerc-io/stack-orchestrator
Basic volume support (#622)
This commit is contained in:
parent
fd5779f967
commit
0f93d30d54
@ -18,6 +18,7 @@ from typing import Any, List, Set
|
||||
|
||||
from app.opts import opts
|
||||
from app.util import get_yaml
|
||||
from app.deploy.k8s.helpers import named_volumes_from_pod_files, volume_mounts_for_service, volumes_for_pod_files
|
||||
|
||||
|
||||
class ClusterInfo:
|
||||
@ -47,6 +48,28 @@ class ClusterInfo:
|
||||
if opts.o.debug:
|
||||
print(f"image_set: {self.image_set}")
|
||||
|
||||
def get_pvcs(self):
|
||||
result = []
|
||||
volumes = named_volumes_from_pod_files(self.parsed_pod_yaml_map)
|
||||
if opts.o.debug:
|
||||
print(f"Volumes: {volumes}")
|
||||
for volume_name in volumes:
|
||||
spec = client.V1PersistentVolumeClaimSpec(
|
||||
storage_class_name="standard",
|
||||
access_modes=["ReadWriteOnce"],
|
||||
resources=client.V1ResourceRequirements(
|
||||
requests={"storage": "2Gi"}
|
||||
)
|
||||
)
|
||||
pvc = client.V1PersistentVolumeClaim(
|
||||
metadata=client.V1ObjectMeta(name=volume_name,
|
||||
labels={"volume-label": volume_name}),
|
||||
spec=spec,
|
||||
)
|
||||
result.append(pvc)
|
||||
return result
|
||||
|
||||
# to suit the deployment, and also annotate the container specs to point at said volumes
|
||||
def get_deployment(self):
|
||||
containers = []
|
||||
for pod_name in self.parsed_pod_yaml_map:
|
||||
@ -56,19 +79,22 @@ class ClusterInfo:
|
||||
container_name = service_name
|
||||
service_info = services[service_name]
|
||||
image = service_info["image"]
|
||||
volume_mounts = volume_mounts_for_service(self.parsed_pod_yaml_map, service_name)
|
||||
container = client.V1Container(
|
||||
name=container_name,
|
||||
image=image,
|
||||
ports=[client.V1ContainerPort(container_port=80)],
|
||||
volume_mounts=volume_mounts,
|
||||
resources=client.V1ResourceRequirements(
|
||||
requests={"cpu": "100m", "memory": "200Mi"},
|
||||
limits={"cpu": "500m", "memory": "500Mi"},
|
||||
),
|
||||
)
|
||||
containers.append(container)
|
||||
volumes = volumes_for_pod_files(self.parsed_pod_yaml_map)
|
||||
template = client.V1PodTemplateSpec(
|
||||
metadata=client.V1ObjectMeta(labels={"app": self.app_name}),
|
||||
spec=client.V1PodSpec(containers=containers),
|
||||
spec=client.V1PodSpec(containers=containers, volumes=volumes),
|
||||
)
|
||||
spec = client.V1DeploymentSpec(
|
||||
replicas=1, template=template, selector={
|
||||
|
@ -26,6 +26,7 @@ class K8sDeployer(Deployer):
|
||||
name: str = "k8s"
|
||||
core_api: client.CoreV1Api
|
||||
apps_api: client.AppsV1Api
|
||||
k8s_namespace: str = "default"
|
||||
kind_cluster_name: str
|
||||
cluster_info : ClusterInfo
|
||||
|
||||
@ -49,17 +50,27 @@ class K8sDeployer(Deployer):
|
||||
self.connect_api()
|
||||
# Ensure the referenced containers are copied into kind
|
||||
load_images_into_kind(self.kind_cluster_name, self.cluster_info.image_set)
|
||||
# Figure out the PVCs for this deployment
|
||||
pvcs = self.cluster_info.get_pvcs()
|
||||
for pvc in pvcs:
|
||||
if opts.o.debug:
|
||||
print(f"Sending this: {pvc}")
|
||||
pvc_resp = self.core_api.create_namespaced_persistent_volume_claim(body=pvc, namespace=self.k8s_namespace)
|
||||
if opts.o.debug:
|
||||
print("PVCs created:")
|
||||
print(f"{pvc_resp}")
|
||||
# Process compose files into a Deployment
|
||||
deployment = self.cluster_info.get_deployment()
|
||||
# Create the k8s objects
|
||||
resp = self.apps_api.create_namespaced_deployment(
|
||||
body=deployment, namespace="default"
|
||||
)
|
||||
|
||||
if opts.o.debug:
|
||||
print("Deployment created.\n")
|
||||
print(f"{resp.metadata.namespace} {resp.metadata.name} \
|
||||
{resp.metadata.generation} {resp.spec.template.spec.containers[0].image}")
|
||||
print(f"Sending this: {deployment}")
|
||||
deployment_resp = self.apps_api.create_namespaced_deployment(
|
||||
body=deployment, namespace=self.k8s_namespace
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("Deployment created:")
|
||||
print(f"{deployment_resp.metadata.namespace} {deployment_resp.metadata.name} \
|
||||
{deployment_resp.metadata.generation} {deployment_resp.spec.template.spec.containers[0].image}")
|
||||
|
||||
def down(self, timeout, volumes):
|
||||
# Delete the k8s objects
|
||||
|
@ -55,3 +55,50 @@ def pods_in_deployment(core_api: client.CoreV1Api, deployment_name: str):
|
||||
def log_stream_from_string(s: str):
|
||||
# Note response has to be UTF-8 encoded because the caller expects to decode it
|
||||
yield ("ignore", s.encode())
|
||||
|
||||
|
||||
def named_volumes_from_pod_files(parsed_pod_files):
|
||||
# Parse the compose files looking for named volumes
|
||||
named_volumes = []
|
||||
for pod in parsed_pod_files:
|
||||
parsed_pod_file = parsed_pod_files[pod]
|
||||
if "volumes" in parsed_pod_file:
|
||||
volumes = parsed_pod_file["volumes"]
|
||||
for volume in volumes.keys():
|
||||
# Volume definition looks like:
|
||||
# 'laconicd-data': None
|
||||
named_volumes.append(volume)
|
||||
return named_volumes
|
||||
|
||||
|
||||
def volume_mounts_for_service(parsed_pod_files, service):
|
||||
result = []
|
||||
# Find the service
|
||||
for pod in parsed_pod_files:
|
||||
parsed_pod_file = parsed_pod_files[pod]
|
||||
if "services" in parsed_pod_file:
|
||||
services = parsed_pod_file["services"]
|
||||
for service_name in services:
|
||||
if service_name == service:
|
||||
service_obj = services[service_name]
|
||||
if "volumes" in service_obj:
|
||||
volumes = service_obj["volumes"]
|
||||
for mount_string in volumes:
|
||||
# Looks like: test-data:/data
|
||||
(volume_name, mount_path) = mount_string.split(":")
|
||||
volume_device = client.V1VolumeMount(mount_path=mount_path, name=volume_name)
|
||||
result.append(volume_device)
|
||||
return result
|
||||
|
||||
|
||||
def volumes_for_pod_files(parsed_pod_files):
|
||||
result = []
|
||||
for pod in parsed_pod_files:
|
||||
parsed_pod_file = parsed_pod_files[pod]
|
||||
if "volumes" in parsed_pod_file:
|
||||
volumes = parsed_pod_file["volumes"]
|
||||
for volume_name in volumes.keys():
|
||||
claim = client.V1PersistentVolumeClaimVolumeSource(claim_name=volume_name)
|
||||
volume = client.V1Volume(name=volume_name, persistent_volume_claim=claim)
|
||||
result.append(volume)
|
||||
return result
|
||||
|
Loading…
Reference in New Issue
Block a user