-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add workload config object to the desired state #267
Comments
Basic example: desiredState:
workloads:
workload1:
runtime: podman
...
runtimeConfig: |
image: docker.io/nginx:latest
commandOptions: ["-p", "{{nginxPort}}:80"]
configs:
myconfig:
binaryData:
mykey1: <base64 encoded data>
data:
nginxPort: 8081
mykey3: |
foo=bar
name=alice |
For inserting the config data into the workload's runtimeConfig, a template engine could be used. For Rust there is a list of available template engines.
Some candidates:
When using a template engine in the runtimeConfig, then environment variables and command-line arguments can easily be created using config objects. |
The following yaml show how the configs could look like: desiredState:
workload:
dashboard:
...
configs:
c1: dashboard_configs
ports: ports
files:
- mount_point: "/some/path/to/file.json"
data: {{c1.json_data_file_content}}
- mount_point: {{/some/path/to/bin_data}}
binary_data: {{c1.some_data}}
runtimeConfig: |
image: fancy_dashboard:latest
commandOptions: [ "-p", "{{ports.access_port}}:80"]
commandArgs: [ "echo", "{{c1.echo_value}}"]
configs:
dashboard_configs:
echo_value: "Hello Ankaios"
json_data_file_content: |
{
some: {
random: string
object: 5
}
}
some_data: dGhpcyBpcyBhIGJpbmFyeSBmaWxl
ports:
access_port: 8081 @windsource suggested the aliasing in the configs attribute of a workload to make it more obvious which config items are used inside a workload configuration. |
Before this fix it was not possible to run the tests from the common folder. This also prohibited running individual test from Visual Studio Code (e.g. for debugging). Issue-Id: #267
I am reviewing the PR #379 adding the necessary data types. Afterwards I will continue on the implementation.
Parsing error: To make the server accept the config every literal as value must be a string so currently I need "8081" as string to get it work. Shall we also allow numbers? Otherwise I have to explicitly write the port in quotes. |
I am strictly against allowing numbers in the ConfigItem. We plan to only use these configs for string templates. With config strings this is easy. The placeholder in the template is replaced by the value of the config. For numbers the config is first parsed into some internal representation and for replacing the template placeholder this internal representation is then converted to a string. This string might differ from the string provided in the yaml config/manifest. This unnecessarily introduces potential errors and leaks implementations details. |
After discussing the config reference complexity with @windsource and @krucod3, we decided to allow only one level of the In addition, we decided to treat every input of replacement as string since the implementation is easier in the first step without considering too many corner cases for replacing with numbers, floats and so on. So we update the prototype to use quotes for the port number. New prototype: desiredState:
workloads:
dashboard:
...
configs:
c1: dashboard_configs
ports: ports
files:
- mountPoint: "/some/path/to/file.json"
data: "{{c1.json_data_file_content}}"
- mountPoint: "/some/path/to/bin_data"
binaryData: "{{c1.some_data}}"
runtimeConfig: |
image: fancy_dashboard:latest
commandOptions: [ "-p", "{{ports.access_port}}:80"]
commandArgs: [ "echo", "{{c1.echo_value}}"]
configs:
dashboard_configs:
echo_value: "Hello Ankaios"
json_data_file_content: |
{
some: {
random: string
object: "5"
}
}
some_data: dGhpcyBpcyBhIGJpbmFyeSBmaWxl
ports:
access_port: "8081" |
Issue-Id: #267 Co-authored-by: Oliver <42932060+inf17101@users.noreply.github.com>
* Add config to state object Issue-Id: #267 * Fix problem with tests not building for common Before this fix it was not possible to run the tests from the common folder. This also prohibited running individual test from Visual Studio Code (e.g. for debugging). Issue-Id: #267 * Improve YAML serialization of ConfigItem Issue-Id: #267 * Add internal config object Issue-Id: #267 * Fix unit tests Issue-Id: #267 * Fix clippy error about unequal enum sizes Issue-Id: #267 * Remove unused import Issue-Id: #267 * Interpret None fields as default instead of failing Issue-Id: #267 * Add configs to filtered state used in the ank CLI * Also update server state if non workload has been changed * Add missing fields in tests Issue-Id: #267 * Remove commented out code Issue-Id: #267 * Fix year in copyright header of new files Issue-Id: #267 * Apply suggestions from code review Co-authored-by: Oliver <42932060+inf17101@users.noreply.github.com> * Remove commented out code Issue-Id: #267 Co-authored-by: Oliver <42932060+inf17101@users.noreply.github.com> * Add missing use statement Issue-Id: #267 * Allow missing workloads in UpdateStateRequeset Issue-Id: #267 * Fix configs in sample objects Issue-Id: #267 * Add missing config Issue-Id: #267 * Fix filtering redundant mask --------- Co-authored-by: Oliver <42932060+inf17101@users.noreply.github.com> Co-authored-by: Oliver Klapper <oliver.klapper@elektrobit.com>
I decided to go with handlebars as template engine, because it is actively maintained, has an easy to use interface which fits well to our objects we work with and it contains just the minimum of required features covering the use cases for rendering configs (loops + if). It is not overblown with many other template engine features and the amount of fetched in dependencies is kept to manageable level. If more features are required in the future it is extensible through the so called helpers. I have already committed some first design decision into the requirements of the server. |
Noting down some corner cases to be considered during implementation:
|
@HorjuRares: I have created a fork in my private account, so that we can work both on the task. I thought about tasks that you can take over:
...
dashboard_workload:
....
files:
- mount_point: "/some/path/to/file.json"
data: {{c1.json_data_file_content}}
- mount_point: "/some/path/to/bin_data"
binary_data: {{c1.some_data}}
....
You can take one of the tasks above if you want. Personally, I would recommend that you start with the config key check, since you know that code path best. If it is done you can move on to one of the other suggested tasks. I have invited you to my fork, branch: 267_workload_config_impl. You should be able to commit there. |
I throw away the original idea of giving the ServerState its own type wrapping the CompleteState, which stores the workload objects unexpanded and expanded, because otherwise too many other fields (such as AgentMap, WorkloadStateDB) are also duplicated. What I am doing now is to keep other parts of the ServerState stable, that I store only the expanded workload states inside the ServerState. I keep the desiredState storing the unexpanded workloads like it is to not break a lot of functionality like filtering the CompleteState inside the server parts (affecting all from impls and so on) and to make it possible to retrieve the unexpanded state over control interface and cli. The StoredWorkloadSpec is the unexpanded workload and the Currently, I am implementing the update logic, which I decided to compare the expanded workloads. Then, I can cover cases like config items changed or workload template config string changed easily. |
After implementing the update logic for workloads with configs, I have tested the following cases:
In addition, for optimization, a workload is not rendered, when no configs are assigned to that workload (empty configs field in the workload configuration). In this case all fields of the workload are not rendered and treated like the previous workload configuration without configs. |
@HorjuRares: I have already implemented task 2 about the files field for mounting files into a workload. I have pushed it to a separate branch, since the files change and logic will be developed in a separate PR. |
The files mounted to a workload task is now a sub issue and I have posted the branch with all up-to-date information inside the sub issue. |
I had a look to the |
I have covered the following State changes according to the table: Configs casesUpdate state cases
Startup cases
|
* Small draft code to try out handlebars * Write design decision for handlebars * Add first swdds and first draft implementation * Fix reference and swdd tags * Add swdd for config renderer * Update rendered workloads only when state is updated * Implement update logic of expanded workloads * Rename workload variables * Skip rendering on no config assignment and introduce error type * Fix update of config item only * Remove in-place allocation of ConfigRenderer * Add comment * Fix server state utests * Add config renderer utests * Add update of configs utest and swdd * Add configs update utests for server state * Rename update_state method * Ignore configs for agent name handling in ank apply * Fix linkage in utest * Add completions for configs in object field mask Issue-Id: #267 * Improve log output in ank cli * Update only desiredState * Refactor set_state function and update plantuml * Write swdd for comparing rendered workloads * Split state format rendering * Fix wrong dependencies workload names in test data * Extract to constant var * Remove not needed references * First basic system test * Rename stest file * Remove notes file * Make utest more strict * Add more stests and link them * Add utests for config key and alias validation * Add config key format stest * Add stests for workload config refs and fix linkage * Add utests for ank apply * Remove duplicated utest * Adapt working with complete state section * Disable wait in utest * Merge main into branch and fix utest * Get rid of conversion in utest * Adapt quickstart doc * Adapt startup-configuration user doc * Extend user tutorial with configs * Add update and delete config user doc * Add comment about unrendered get complete state * Fix rust contol interface example * Add utest linkage * Add linkage to utest for config rendering * Fix missing swdd prefix in linkage * Wording in comment Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Rename api_format method * Fix naming convention swdd rationale * Change swdd for selecting workloads for agents * Add newline to swdd rationale Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Rename utest Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Use mockall double for import Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Output error message Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Space in utest linkage Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Change comment in utest Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Fix comment in stest documentation * Fix comments for precondition * Remove config_key from workload config map and insert utest * Throw specific error upon not existing config key * Adapt doc agent field description Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Change linkage to sub chapter Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> * Remove plurar * Rename update state file in stest * Revert to normal yaml string Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com> --------- Co-authored-by: Holger Dormann <holger.dormann@elektrobit.com> Co-authored-by: Kaloyan <36224699+krucod3@users.noreply.github.com>
PR reviewed and merged. Summary written in the issue description. Issue can be closed. |
Description
Currently the only way to configure workloads is to add configuration parameters to the runtime. This enhancement shall allow to decouple configuration from workload such that the same workload can be used with different configurations. For that a new object
config
shall be created that also resides in Ankaios manifests parallel toworkload
.A config shall contain key-value pairs that can be used as environment variables, command-line arguments or as read-only configuration files to be provide to the workload.
To limit resource usage (probably the config map will be part of the complete state and thus consume RAM) we should limit the size of a config to a maximum value (e.g. 1MB).
For the values, text and binary (base-64 encoded) data shall be allowed.
When providing a config value as file then owner and mode shall also be configurable.
Maybe we reuse the same format as the Kubernetes ConfigMap, for example:
It should be possible that one workload uses several configs. It should also be possible that all key/value pairs of one config are expanded to environment variables.
Goals
Separate config and workload such that the same workload can be used with different configurations. That allows also updating the config separately from the workload.
Final result
Summary
The
desiredState
now supports theconfigs
field for defining configuration items that can be assigned to workloads. The workload configuration has aconfigs
field to assign configs of thedesriedState.configs
by defining an config name alias as key and the key of the config item as value. For rendering workload fields with configuration items, the handlebars-rs Rust crate was introduced. It supports a sufficient and not overwhelming feature set for the config rendering use case (variables, loops, conditionals).The following workload fields are supporting templated strings:
Furthermore, for config aliases and config keys they are pointing to and also the config keys in the
desriedState.configs
field a character check was added. Supported are only normal characters, '_' and '-' (same like for workloads).The Ankaios server renders the state at each update of the state (startup, subsequent updates) and only if workloads having configs assigned. The Ankaios server stores the rendered workloads separated from the CompleteState to avoid excessive on-the-fly rendering when Ankaios components like Ankaios agents, etc connects and to be able to return the unrendered state when requesting the CompleteState.
Tasks
ank apply
command to support workload configsank apply
changed logic and fix the utestutest_generate_state_obj_and_filter_masks_from_manifests_no_workload_provided
(the prod code does now an exit(0))[a-zA-Z0-9-_]
(same like workloads), requirements + utestsank delete config
andank get configs
#392The text was updated successfully, but these errors were encountered: