Converting Gigabytes to bytes in helm templates - go

I have a chart for kafka, that has a pvc size defined in its values file like so: 20Gi. I also have a configmap, that has a definition that it takes in bytes, like so: log.retention.bytes=21474836480.
I'm trying to get my chart to use the same value defined in size in the values file, in the configmap (hopefully, do some arithmetics on it before, like taking away a constant value to reserve some extra space)
I've been looking for a while to see if there is such a function built in to helm templates, or a way to create my own functions, with not much luck.
Ideally, I'm looking for something like this:
log.retention.bytes={{ .Values.persistence.size | convert-to-bytes | substract 10000 }}

You can use the div Sprig function. For example, you could do:
{{ div .Values.persistence.size 1024 }}
If you'd like to perform a subtraction on the result, you can use the sub function. For example:
{{ sub (div .Values.persistence.size 1024) 10000 }}

I've managed to get results I need with this code:
log.retention.bytes={{ subf (trimSuffix "Gi" .Values.persistence.size | mulf 1073741824) 10000 | floor }}
subf and mulf are used because value in "Gi" can often be floor not intger and sub and mulf are supposed to be used only with integers.

Related

Set the name for each ParallelFor iteration in KFP v2 on Vertex AI

I am currently using kfp.dsl.ParallelFor to train 300 models. It looks something like this:
...
models_to_train_op = get_models()
with dsl.ParallelFor(models_to_train_op.outputs["data"], parallelism=100) as item:
prepare_data_op = prepare_data(item)
train_model_op = train_model(prepare_data_op["train_data"]
...
Currently, the iterations in Vertex AI are labeled in a dropdown as something like for-loop-worker-0, for-loop-worker-1, and so on. For tasks (like prepare_data_op, there's a function called set_display_name. Is there a similar method that allows you to set the iteration name? It would be helpful to relate them to the training data so that it's easier to look through the dropdown UI that Vertex AI provides.
I reached out to a contact I have at Google. They recommended that you can pass the list that is passed to ParallelFor to set_display_name for each 'iteration' of the loop. When the pipeline is compiled, it'll know to set the corresponding iteration.
# Create component that returns a range list
model_list_op = model_list(n_models)
# Parallelize jobs
ParallelFor(model_list_op.outputs["model_list"], parallelism=100) as x:
x.set_display_name(str(model_list_op.outputs["model_list"]))

Inserting template name as class

When creating a Go template, you can give it a name, like in this example, "my_home_template":
var tmplHome = template.Must(template.New("my_home_template").Funcs(funcMap).ParseFiles("templates/base.tmpl", "templates/content_home.tmpl"))
How can I get that template name and use it inside the actual template file?
Ultimately I just want to define a convenient css class, like so:
<body class="my_home_template">
Here's a working solution, taking mkopriva's advice:
When executing a template, pass some custom parameter with dummy data. Here, I just create a "PageHome" parameter to pass to the template, and value is a simple "1", but it could be any value:
tmplHome.ExecuteTemplate(w, "base", map[string]interface{}{"PageHome": "1", "Data": events, "UserFirstName": &u.FirstName, "UserProfilePic": &u.ProfilePic})
Then, inside the template itself, a simple if statement to check if the parameter exists, and do something accordingly:
{{ if .PageHome }}
<body class="PageHome">
{{ else }}
<body>
{{ end }}
All my other template executions don't pass a "PageHome" parameter at all, so the if statement never passes as true for them.
There's probably a more advanced solution using a functions via a template function map, and having a consistent "PageType":"something" parameter in all template executions, but in the end you still have to define a parameter per template execution and still have to build up if statements in your templates anyways.

Render value to tenths place in nunjucks template?

Using the round() filter I can achieve the correct precision to the tenths place as in
{{ value | round(1) }}
however I still want to display the tenths place if value is zero or a whole integer. (0.0 instead of 0, 3.0 instead of 3)
Is there a different method or other way to render all values to the tenths place?
Add you own filter
var env = nunjucks.configure(...
env.addFilter('round1', function(num) {
if (!isNaN(num))
return '???';
return parseFloat(num).toFixed(1);
});
Usage
{{ value | round1 }}
Here is the logic for the custom filter since the round filter will not maintain a tenths place for zero or whole integers:
nunjucks.configure().addFilter('tenths', function(num) {
return parseFloat(num).toFixed(1);
});
Then usage is the same as any filter:
{{ num | tenths }}

How to convert a variable value on the fly in Ansible/Jinja2 template?

I need to set a properties in two different files through Ansible/Jinja2 template file. In one of the files the values should be comma-separated, in the other space-separated.
Currently I use two different variables:
values_space_separated = value1 value2 value3
values_comma_separated = value1,value2,value3
How can I avoid duplication?
Is there a way to convert a value of the variable on-the-fly?
You could always use the regex_replace filter.
So if you normally define the variable as:
values = value1,value2,value3
Then if you need it space separated instead then you could always just do this:
{{ values | regex_replace(',',' ') }}

Show default content in a template if an object is nil otherwise show based on the set property

In my template, I would like to include some default meta tags (90% of the time). However, when a specific property is set, I would like to show a different set of text.
I know I can set an anonymous struct and set a property with either "default" or "some-x". However, this means, I need to add an anonymous struct to 90% of my handlers that just currently pass nil.
Is there way to do something like
{{if eq . nil}}
// default meta tag
{{else if eq .MetaValue "some-x"}}
//other
{{end}}
If I try something like my above code, it compiles but doesn't do what I want. Appreciate any suggestions on how to handle it properly without adding a lot of boiler plate.
Thanks!
{{if not .}}
output when . is nil or otherwise empty including
false, 0, and any array, slice, map, or string of length zero
{{else if eq .MetaValue "some-x"}}
// some-x case
{{else}}
// other case
{{end}}
If you want to ensure you're only checking against nil and not 0, false, the empty string, or any other falsey type, you can use the kindIs function to accomplish this.
{{ if kindIs "invalid" . }}
// only if variable is literally nil. falsey values will fallthrough.
{{ else if eq .MetaValue "some-x" }}
// other
{{ else }}
// final case, if any
{{ end }}
I've been recently facing an issue with identifying nil vs 0 values in a Helm Chart (which uses Go templates, including sprig) and haven't found any solutions posted, so I thought I'd add mine here.
I came up with a kind of ugly solution which is to quote the value and then check for a string that matches "<nil>" (with quotes, so you'd actually be checking (quote .Values.thing | eq "\"<nil>\"")). This allows differentiating tests against empty values vs defined 0 values. In my case, I was trying to build a config file where some default options were non-0, so when 0 was explicitly set, I wanted to know that 0 was set instead of just omitted.
Hopefully this can be a help to someone else.
It would be nice to have a better way to do this, but so far I haven't found anything that doesn't require creating and adding my own template functions.

Resources