Add post-processing to fix chart name and description

This commit is contained in:
Prathamesh Musale 2025-11-20 14:26:57 +05:30
parent 81f102f110
commit bf4c5571a7
2 changed files with 78 additions and 79 deletions

View File

@ -24,8 +24,7 @@ kompose version
### 1. Create spec file
```bash
laconic-so --stack <stack-name> deploy init \
--deploy-to k8s \
laconic-so --stack <stack-name> deploy --deploy-to k8s init \
--kube-config ~/.kube/config \
--output spec.yml
```
@ -42,8 +41,7 @@ laconic-so --stack <stack-name> deploy create \
### 3. Deploy to Kubernetes
```bash
cd my-deployment/chart
helm install my-release ./ --namespace zenith --create-namespace
helm install my-release my-deployment/chart
kubectl get pods -n zenith
```
@ -64,8 +62,7 @@ my-deployment/
```bash
# Generate chart for stage1-zenithd
laconic-so --stack stage1-zenithd deploy init \
--deploy-to k8s \
laconic-so --stack stage1-zenithd deploy --deploy-to k8s init \
--kube-config ~/.kube/config \
--output stage1-spec.yml
@ -75,6 +72,5 @@ laconic-so --stack stage1-zenithd deploy create \
--helm-chart
# Deploy
cd stage1-deployment/chart
helm install stage1-zenithd ./ --namespace zenith --create-namespace
helm install stage1-zenithd stage1-deployment/chart
```

View File

@ -30,16 +30,46 @@ from stack_orchestrator.deploy.k8s.helm.kompose_wrapper import (
get_kompose_version,
convert_to_helm_chart
)
from stack_orchestrator.util import get_yaml
def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = None) -> None:
def _post_process_chart(chart_dir: Path, chart_name: str) -> None:
"""
Post-process Kompose-generated chart to fix common issues.
Fixes:
1. Chart.yaml name, description and keywords
TODO:
- Add defaultMode: 0755 to ConfigMap volumes containing scripts (.sh files)
"""
yaml = get_yaml()
# Fix Chart.yaml
chart_yaml_path = chart_dir / "Chart.yaml"
if chart_yaml_path.exists():
chart_yaml = yaml.load(open(chart_yaml_path, "r"))
# Fix name
chart_yaml["name"] = chart_name
# Fix description
chart_yaml["description"] = f"Generated Helm chart for {chart_name} stack"
# Fix keywords
if "keywords" in chart_yaml and isinstance(chart_yaml["keywords"], list):
chart_yaml["keywords"] = [chart_name]
with open(chart_yaml_path, "w") as f:
yaml.dump(chart_yaml, f)
def generate_helm_chart(stack_path: str, spec_file: str, deployment_dir: str = None) -> None:
"""
Generate a self-sufficient Helm chart from stack compose files using Kompose.
This is completely separate from the existing k8s deployment flow.
Args:
stack_name: Name of the stack
stack_path: Path to the stack directory
spec_file: Path to the deployment spec file
deployment_dir: Optional directory for deployment output
@ -49,7 +79,6 @@ def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = N
stack.yml # Reference
chart/ # Self-sufficient Helm chart
Chart.yaml
values.yaml (generated by Kompose)
README.md
templates/
*.yaml
@ -69,11 +98,18 @@ def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = N
- Generate comprehensive values.yaml documentation
"""
# 1. Setup deployment directory
parsed_stack = get_parsed_stack_config(stack_path)
stack_name = parsed_stack.get("name", stack_path)
# 1. Check Kompose availability
if not check_kompose_available():
error_exit("kompose not found in PATH.\n")
# 2. Setup deployment directory
if deployment_dir:
deployment_dir_path = Path(deployment_dir)
else:
deployment_dir_path = Path("deployment-001")
deployment_dir_path = Path(f"{stack_name}-deployment")
if deployment_dir_path.exists():
error_exit(f"Deployment directory already exists: {deployment_dir_path}")
@ -83,12 +119,12 @@ def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = N
deployment_dir_path.mkdir(parents=True)
# 2. Copy spec and stack files to deployment directory (for reference)
# 3. Copy spec and stack files to deployment directory (for reference)
spec_path = Path(spec_file).resolve()
if not spec_path.exists():
error_exit(f"Spec file not found: {spec_file}")
stack_file_path = get_stack_path(stack_name).joinpath(constants.stack_file_name)
stack_file_path = get_stack_path(stack_path).joinpath(constants.stack_file_name)
if not stack_file_path.exists():
error_exit(f"Stack file not found: {stack_file_path}")
@ -99,34 +135,26 @@ def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = N
print(f"Copied spec file: {spec_path}")
print(f"Copied stack file: {stack_file_path}")
# 3. Get compose files from stack
parsed_stack = get_parsed_stack_config(stack_name)
# 4. Get compose files from stack
pods = get_pod_list(parsed_stack)
if not pods:
error_exit(f"No pods found in stack: {stack_name}")
error_exit(f"No pods found in stack: {stack_path}")
# Get clean stack name from stack.yml
chart_name = stack_name.replace("_", "-").replace(" ", "-")
if opts.o.debug:
print(f"Found {len(pods)} pod(s) in stack: {pods}")
compose_files = []
for pod in pods:
pod_file = get_pod_file_path(stack_name, parsed_stack, pod)
pod_file = get_pod_file_path(stack_path, parsed_stack, pod)
if not pod_file.exists():
error_exit(f"Pod file not found: {pod_file}")
compose_files.append(pod_file)
if opts.o.debug:
print(f"Found compose file: {pod_file.name}")
# 4. Check Kompose availability
if not check_kompose_available():
error_exit(
"kompose not found in PATH.\n"
"Install from: https://kompose.io/installation/\n"
" - Linux: curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-linux-amd64 -o kompose\n"
" - macOS: brew install kompose"
)
try:
version = get_kompose_version()
print(f"Using kompose version: {version}")
@ -135,7 +163,6 @@ def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = N
# 5. Create chart directory and invoke Kompose
chart_dir = deployment_dir_path / "chart"
chart_name = stack_name.replace("_", "-").replace(" ", "-") # Helm chart names prefer dashes
print(f"Converting {len(compose_files)} compose file(s) to Helm chart using Kompose...")
@ -150,10 +177,13 @@ def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = N
except Exception as e:
error_exit(f"Helm chart generation failed: {e}")
# 6. Generate README.md with basic installation instructions
# 6. Post-process generated chart
_post_process_chart(chart_dir, chart_name)
# 7. Generate README.md with basic installation instructions
readme_content = f"""# {chart_name} Helm Chart
Generated by laconic-so from stack: {stack_name}
Generated by laconic-so from stack: `{stack_path}
## Prerequisites
@ -164,20 +194,25 @@ Generated by laconic-so from stack: {stack_name}
## Installation
```bash
# Create namespace (optional)
kubectl create namespace zenith
# Install the chart
helm install {chart_name} ./ --namespace zenith
helm install {chart_name} {chart_dir}
# Check deployment status
kubectl get pods -n zenith
kubectl get pods
```
## Upgrade
To apply changes made to chart, perform upgrade:
```bash
helm upgrade {chart_name} {chart_dir}
```
## Uninstallation
```bash
helm uninstall {chart_name} --namespace zenith
helm uninstall {chart_name}
```
## Configuration
@ -191,38 +226,6 @@ Edit the generated template files in `templates/` to customize:
- Resource limits (CPU, memory)
- Persistent volume sizes
- Replica counts
TODO: values.yaml will be enhanced in future versions to provide a cleaner configuration interface.
## Generated Files
- `Chart.yaml` - Chart metadata
- `templates/` - Kubernetes resource manifests
- Deployments
- Services
- PersistentVolumeClaims
- ConfigMaps
## Post-Processing TODO
The following enhancements are planned:
- Parameterized values.yaml with common configuration options
- StatefulSet conversion for stateful services (databases, validators)
- Embedded deployment artifacts (genesis files, configs) as ConfigMaps
- Secret templates for sensitive data (validator keys, passwords)
- Init containers for setup and configuration
- Enhanced Chart.yaml metadata
## Notes
This chart is generated from compose files and may require manual adjustments for production use:
1. Review resource limits in deployment manifests
2. Configure persistent volume storage classes for your cluster
3. Set up ingress for external access if needed
4. Configure secrets for sensitive data (passwords, keys)
5. Adjust service types (ClusterIP, NodePort, LoadBalancer) based on your needs
For more information, see the laconic-so documentation.
"""
readme_path = chart_dir / "README.md"
@ -238,7 +241,7 @@ For more information, see the laconic-so documentation.
print(f"\nChart details:")
print(f" Name: {chart_name}")
print(f" Location: {chart_dir.absolute()}")
print(f" Stack: {stack_name}")
print(f" Stack: {stack_path}")
# Count generated files
template_files = list((chart_dir / "templates").glob("*.yaml")) if (chart_dir / "templates").exists() else []
@ -259,8 +262,8 @@ For more information, see the laconic-so documentation.
print(f" ls templates/")
print(f"")
print(f" 3. Install to Kubernetes:")
print(f" helm install {chart_name} ./ --namespace zenith --create-namespace")
print(f" helm install {chart_name} {chart_dir}")
print(f"")
print(f" 4. Check deployment:")
print(f" kubectl get pods -n zenith")
print(f" kubectl get pods")
print(f"")