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

View File

@ -30,16 +30,46 @@ from stack_orchestrator.deploy.k8s.helm.kompose_wrapper import (
get_kompose_version, get_kompose_version,
convert_to_helm_chart 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. Generate a self-sufficient Helm chart from stack compose files using Kompose.
This is completely separate from the existing k8s deployment flow.
Args: Args:
stack_name: Name of the stack stack_path: Path to the stack directory
spec_file: Path to the deployment spec file spec_file: Path to the deployment spec file
deployment_dir: Optional directory for deployment output 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 stack.yml # Reference
chart/ # Self-sufficient Helm chart chart/ # Self-sufficient Helm chart
Chart.yaml Chart.yaml
values.yaml (generated by Kompose)
README.md README.md
templates/ templates/
*.yaml *.yaml
@ -69,11 +98,18 @@ def generate_helm_chart(stack_name: str, spec_file: str, deployment_dir: str = N
- Generate comprehensive values.yaml documentation - 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: if deployment_dir:
deployment_dir_path = Path(deployment_dir) deployment_dir_path = Path(deployment_dir)
else: else:
deployment_dir_path = Path("deployment-001") deployment_dir_path = Path(f"{stack_name}-deployment")
if deployment_dir_path.exists(): if deployment_dir_path.exists():
error_exit(f"Deployment directory already exists: {deployment_dir_path}") 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) 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() spec_path = Path(spec_file).resolve()
if not spec_path.exists(): if not spec_path.exists():
error_exit(f"Spec file not found: {spec_file}") 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(): if not stack_file_path.exists():
error_exit(f"Stack file not found: {stack_file_path}") 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 spec file: {spec_path}")
print(f"Copied stack file: {stack_file_path}") print(f"Copied stack file: {stack_file_path}")
# 3. Get compose files from stack # 4. Get compose files from stack
parsed_stack = get_parsed_stack_config(stack_name)
pods = get_pod_list(parsed_stack) pods = get_pod_list(parsed_stack)
if not pods: 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: if opts.o.debug:
print(f"Found {len(pods)} pod(s) in stack: {pods}") print(f"Found {len(pods)} pod(s) in stack: {pods}")
compose_files = [] compose_files = []
for pod in pods: 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(): if not pod_file.exists():
error_exit(f"Pod file not found: {pod_file}") error_exit(f"Pod file not found: {pod_file}")
compose_files.append(pod_file) compose_files.append(pod_file)
if opts.o.debug: if opts.o.debug:
print(f"Found compose file: {pod_file.name}") 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: try:
version = get_kompose_version() version = get_kompose_version()
print(f"Using kompose version: {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 # 5. Create chart directory and invoke Kompose
chart_dir = deployment_dir_path / "chart" 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...") 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: except Exception as e:
error_exit(f"Helm chart generation failed: {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 readme_content = f"""# {chart_name} Helm Chart
Generated by laconic-so from stack: {stack_name} Generated by laconic-so from stack: `{stack_path}
## Prerequisites ## Prerequisites
@ -164,20 +194,25 @@ Generated by laconic-so from stack: {stack_name}
## Installation ## Installation
```bash ```bash
# Create namespace (optional)
kubectl create namespace zenith
# Install the chart # Install the chart
helm install {chart_name} ./ --namespace zenith helm install {chart_name} {chart_dir}
# Check deployment status # 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 ## Uninstallation
```bash ```bash
helm uninstall {chart_name} --namespace zenith helm uninstall {chart_name}
``` ```
## Configuration ## Configuration
@ -191,38 +226,6 @@ Edit the generated template files in `templates/` to customize:
- Resource limits (CPU, memory) - Resource limits (CPU, memory)
- Persistent volume sizes - Persistent volume sizes
- Replica counts - 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" readme_path = chart_dir / "README.md"
@ -238,7 +241,7 @@ For more information, see the laconic-so documentation.
print(f"\nChart details:") print(f"\nChart details:")
print(f" Name: {chart_name}") print(f" Name: {chart_name}")
print(f" Location: {chart_dir.absolute()}") print(f" Location: {chart_dir.absolute()}")
print(f" Stack: {stack_name}") print(f" Stack: {stack_path}")
# Count generated files # Count generated files
template_files = list((chart_dir / "templates").glob("*.yaml")) if (chart_dir / "templates").exists() else [] 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" ls templates/")
print(f"") print(f"")
print(f" 3. Install to Kubernetes:") 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"")
print(f" 4. Check deployment:") print(f" 4. Check deployment:")
print(f" kubectl get pods -n zenith") print(f" kubectl get pods")
print(f"") print(f"")