Skip to content
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 limayaml param settings to provisioning script environment #2570

Merged
merged 1 commit into from
Sep 7, 2024

Conversation

jandubois
Copy link
Member

@jandubois jandubois commented Aug 30, 2024

They will be prefixed with PARAM_, so param.FOO becomes PARAM_FOO.

This is useful because parameter substitution happens when a template is instantiated, so [ "{{.Param.ROOTFUL}}" = true ] becomes [ "true" = true ] in the cloud-init-output.log.

This mechanism also works better when the parameter contains quotes, which would break a simplistic FOO="{{.Param.FOO}}".

Test sample:

param:
  FOO: 'foo"bar'

provision:
- mode: system
  script: |
    echo "$PARAM_FOO"

Output:

LIMA 2024-08-30T09:13:11-07:00| Executing /mnt/lima-cidata/provision.system/00000000
foo"bar
LIMA 2024-08-30T09:13:11-07:00| Exiting with code 0

Example of real-life usage (from #2515) will be to replace

-     # Setting shell variable makes it easier to read cloud-init-output.log
-     readonly ROOTFUL="{{.Param.ROOTFUL}}"
-     if [ "$ROOTFUL" = true ]; then
+     if [ "$PARAM_ROOTFUL" = true ]; then

Copy link
Member Author

@jandubois jandubois left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs docs!

Also wondering if probes should have access too (they currently don't have access to LIMA_CIDATA_* variables, I think).

@jandubois jandubois marked this pull request as draft August 30, 2024 17:20
@jandubois jandubois force-pushed the param-env branch 2 times, most recently from b13d8b1 to 22676c1 Compare September 6, 2024 06:32
@jandubois jandubois marked this pull request as ready for review September 6, 2024 06:35
@jandubois
Copy link
Member Author

I'm not proud of the hack to make the $PARAM_* variables available to the probes, but I couldn't figure out a cleaner way as long as we support arbitrary interpreters via the hashbang line.

Anyways, I think the PR is ready for review now.

Copy link
Contributor

@norio-nomura norio-nomura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks like something I considered before implementing #2498 but ultimately abandoned because it seemed too complex for me. I find it impressive and at the same time feel that it was indeed too challenging for me.

I haven't finished reading the probes hack yet, but I'll share what I understand so far.

pkg/limayaml/validate_test.go Show resolved Hide resolved
pkg/cidata/cidata.TEMPLATE.d/boot.sh Show resolved Hide resolved
@jandubois jandubois force-pushed the param-env branch 2 times, most recently from 81f7fda to b8fcab6 Compare September 6, 2024 18:19
@jandubois
Copy link
Member Author

This change looks like something I considered before implementing #2498

This change just build on top of #2498, which is still needed so we can use {{.Param.Key}} in all the places that are not provisioning scripts or probes.

I haven't finished reading the probes hack yet, but I'll share what I understand so far.

I've moved the hack to a separate function and added rather verbose documentation about it. It feels kind of too long, but maybe it is useful.

Copy link
Contributor

@norio-nomura norio-nomura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation and comments for prefixExportParam() made it very clear. Thanks to that, I can suggest a simpler command.
Adding tests to test-misc.yaml is also very clear and good.

examples/default.yaml Show resolved Hide resolved
hack/test-templates.sh Show resolved Hide resolved
pkg/cidata/cidata.TEMPLATE.d/user-data Show resolved Hide resolved
pkg/hostagent/requirements.go Show resolved Hide resolved
pkg/limayaml/validate.go Show resolved Hide resolved
They will be prefixed with `PARAM_`, so `param.FOO` becomes `PARAM_FOO`.

This is useful because parameter substitution happens when a template is
instantiated, so `[ "{{.Param.ROOTFUL}}" = true ]` becomes `[ "true" = true ]`
in the cloud-init-output.log.

This mechanism also works better when the parameter contains quotes, which
would break a simplistic `FOO="{{.Param.FOO}}"`.

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
Copy link
Contributor

@norio-nomura norio-nomura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

pkg/limayaml/validate_test.go Show resolved Hide resolved
pkg/limayaml/validate_test.go Show resolved Hide resolved
@jandubois
Copy link
Member Author

LGTM!

🙏 Thanks! All checks have passed, so I will merge now.

@jandubois jandubois merged commit 54ba0b3 into lima-vm:master Sep 7, 2024
27 checks passed
@jandubois jandubois deleted the param-env branch September 7, 2024 07:46
@AkihiroSuda AkihiroSuda added this to the v1.0 milestone Sep 7, 2024
@nirs
Copy link
Contributor

nirs commented Sep 8, 2024

This is awesome improvement, I wanted to ask how to inject values from the instance yaml to the cloud-init scripts.

However the names makes this harder to understand. Maybe rename to:

env:
  MY_KEY: VALUE
provision:
  - mode: system
    script: |
      #!/bin/bash
      echo "MY_KEY"

No magic prefix, what you put in env added to the provision scripts.

This is also similar to docker/podman --env flag.

@norio-nomura
Copy link
Contributor

Maybe rename to:

The .env field already exists. However, it had too broad of an impact to use solely for modifying the behavior of scripts within limayaml. That's why I wanted variables that could only be used in Lima, and after some consideration, I implemented .param.

@nirs
Copy link
Contributor

nirs commented Sep 9, 2024

Yes being able to limit the scope is nice. Did you consider something like this?

env:
  KEY: global
bootEnv:
  BOOT_KEY: boot
provision:
  - mode: system
    script: |
      echo $KEY       # -> gloabl
      echo $BOOT_KEY  # -> boot
probes:
  - mode: system
    script: |
      echo $KEY       # -> gloabl
      echo $BOOT_KEY  # -> boot

Since all provision steps are run by the same global boot.sh script, we can pass the bootEnv to the scripts by exporting the boot env vars from the script.

I did not check how probes are run, but since they are scripts there must be some shell running them and we can modify its environment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants