Move2Kube allows custom template files to be added to any directory. This example illustrates this by adding a custom Helm chart.
workspace
and make it the current working directory. Asume all commands are executed within this directory.$ mkdir workspace && cd workspace
$ curl https://move2kube.konveyor.io/scripts/download.sh | bash -s -- -d samples/enterprise-app/src -r move2kube-demos
$ ls src
README.md config-utils customers docs frontend gateway orders
In this project, all the apps have a pom.xml file. Use a custom transformer to place a Helm chart created from a template into each of those project directories.
customizations
sub-directory.$ curl https://move2kube.konveyor.io/scripts/download.sh | bash -s -- -d add-custom-files-directories-in-custom-locations -r move2kube-transformers -o customizations
-c
flag.$ move2kube transform -s src/ -c customizations/ --qa-skip
Once the output is generated, one Helm chart was generated for each service and placed within the service directory. Also, note that every Helm chart project is named after the service it is meant for. The contents are shown below for reference:
{% raw %}
$ tree myproject
myproject/
├── config-utils
│ ├── helm-chart
│ │ └── config-utils
│ │ ├── Chart.yaml
│ │ ├── templates
│ │ │ ├── config-utils-deployment.yaml
│ │ │ ├── config-utils-ingress.yaml
│ │ │ └── config-utils-service.yaml
│ │ └── values.yaml
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── io
│ └── konveyor
│ └── demo
│ └── config
│ └── ApplicationConfiguration.java
This custom transformer is more advanced compared to previous cases. It uses a Starlark script (customhelmchartgen.star
) and several templatization features to achieve the per-service Helm chart requirement. Notice the {% raw %}{{\ .ServiceName\ }}{% endraw %}
template in the file names of custom Helm chart template in the templates
sub-directory. The contents of the add-custom-files-directories-in-custom-locations
custom transformer are shown below:
{% raw %}customization/add-custom-files-directories-in-custom-locations/
├── customhelmchartgen.star
├── customhelmchartgen.yaml
└── templates
└── helm-chart
└── {{\ .ServiceName\ }}
├── Chart.yaml
├── templates
│ ├── {{\ .ServiceName\ }}-deployment.yaml
│ ├── {{\ .ServiceName\ }}-ingress.yaml
│ └── {{\ .ServiceName\ }}-service.yaml
└── values.yaml{% endraw %}
The code of the Starlark script (cat customizations/add-custom-files-directories-in-custom-locations/customhelmchartgen.star
) is shown below. At a high level, the custom transformer detects a Java project if it finds pom.xml
in the directory when the directory_detect()
function is invoked in the detect phase. Once the Java project is detected, the corresponding project path and service name are passed to the transform phase through Move2Kube.
In the transform phase, the transform()
function is invoked with the discovered service artifacts from the detect phase. These artifacts are used to fill the Helm chart templates shown above and produced as the output in a per-service directory structure.
{% raw %}PomFile = "pom.xml"
# Performs the detection of pom file and extracts service name
def directory_detect(dir):
dataFilePath = fs.pathjoin(dir, PomFile)
if fs.exists(dataFilePath):
serviceName = getServiceName(dataFilePath)
return {serviceName: [{
"paths": {"ProjectPath": [dir]} }] }
# Creates the customized helm chart for every service
def transform(new_artifacts, old_artifacts):
pathMappings = []
artifacts = []
pathTemplate = "{{ SourceRel .ServiceFsPath }}"
for v in new_artifacts:
serviceName = v["configs"]["Service"]["serviceName"]
dir = v['paths']['ProjectPath'][0]
# Create a path template for the service
pathTemplateName = serviceName.replace("-", "") + 'path'
tplPathData = {'ServiceFsPath': dir, 'PathTemplateName': pathTemplateName}
pathMappings.append({'type': 'PathTemplate', \
'sourcePath': pathTemplate, \
'templateConfig': tplPathData})
# Since the helm chart uses the same templating character {{ }} as Golang templates,
# we use `SpecialTemplate` type here where the templating character is <~ ~>.
# The `Template` type can be used for all normal cases
pathMappings.append({'type': 'SpecialTemplate', \
'destinationPath': "{{ ." + pathTemplateName + " }}", \
'templateConfig': {'ServiceFsPath': dir, 'ServiceName': serviceName}})
pathMappings.append({'type': 'Source', \
'sourcePath': "{{ ." + pathTemplateName + " }}",
'destinationPath': "{{ ." + pathTemplateName + " }}"})
return {'pathMappings': pathMappings, 'artifacts': artifacts}
# Extracts service name from pom file
def getServiceName(filePath):
data = fs.read(filePath)
lines = data.splitlines()
for l in lines:
if 'artifactId' in l:
t = l.split('>')
t2 = t[1].split('<')
return t2[0]{% endraw %}