-
Notifications
You must be signed in to change notification settings - Fork 62
Add docs about execution order of Cloud-init files, steps, and substeps #2294
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
base: main
Are you sure you want to change the base?
Conversation
1b965ae to
1e6610d
Compare
| - The execution order of multiple `substeps` (such as `files`, `commands`, `environment` etc.) within a single `step` is not guaranteed. | ||
| Therefore, when you have multiple `substeps` that related to each other, please do not define them in a single `step`. | ||
| Instead, you can split the `substeps` into multiple `steps` which are ensured to be executed by the definition order. | ||
| - The name of `steps` and output of `substeps` will be output to system journal log which can be viewed by the command `journalctl -u 'elemental*'`. | ||
| - It is highly recommended to declare the `name` property of *steps*, so that it will be easier to investigate the output of `journalctl -u 'elemental*'` by the name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording here is pretty confusing.
In other places in the documentation, it's referred to as stage and action:
stages:
fs: # <-- this is a "stage"
- name: "foobar" # <-- this is an "action"
command: echo foobarThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the fs is obviously an stage.
The properties in it seems is called as "steps" in other documents, instead of action, e.g., https://rancher.github.io/elemental-toolkit/docs/customizing/stages/

And https://rancher.github.io/elemental-toolkit/docs/reference/cloud_init/

How do you think?
Should we change steps to actions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point I'd like to clarify is the substeps which is not explicitly described anywhere.
stages:
fs: # <-- this is a "stage"
- name: "foobar" # <-- this is an "step title"
commands: # <-- I'd like to call this as a substep.
- echo foobar
- command2
files: # <-- I'd like to call this as a substep.
- path: ..
content: ...
- path: ..
content: ...
It is not clear about if the commands are executed before files or reverse.
(But of course inside the same substep, such as commands, it is an array, each item in it is executed by the definition order).
| - During upgrades, installation, deployments , and resets | ||
|
|
||
| Cloud-init files in `/system/oem`, `/oem` and `/usr/local/oem` are applied in 5 different phases: `boot`, `network`, `fs`, `initramfs` and `reconcile`. All the available cloud-init keywords can be used in each stage. Additionally, it's possible also to hook before or after a stage has run, each one has a specific stage which is possible to run steps: `boot.after`, `network.before`, `fs.after` etc. | ||
| Cloud-init files in `/system/oem`, `/oem`, `/usr/local/oem`, and kernel boot args are applied in 5 different phases: `boot`, `network`, `fs`, `initramfs` and `reconcile`. All the available cloud-init keywords can be used in each stage. Additionally, it's possible also to hook before or after a stage has run, each one has a specific stage which is possible to run steps: `boot.after`, `network.before`, `fs.after` etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reconcile phase is special, because it's executed repeatedly on a timer. The other phases are executed during system boot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, here you can see, the term phases is used for stages such as fs. Should we unify them? But probably it is not that confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would agree to change phases to stages in the above examples 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frelon Changed to stages, but only for above case.
| Each cloud-config file is loaded and executed only at the appropriate stage, this allows further components to emit their own stages at the desired time. | ||
|
|
||
| _Note_: | ||
| - The execution order of multiple `substeps` (such as `files`, `commands`, `environment` etc.) within a single `step` is not guaranteed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, this is not true. The execution order within a stage should be as-listed in each file and each group of actions in each file should be executed according to the alphabetical order of filenames.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I'd like to clarify.
The order is not the order defined in the yaml, this is mainly because the definition order of properties in yaml(or json) is not respected.
stages:
fs:
- name: test
environment_file: /tmp/env_file1
environment:
ENV1: this is ENV1
files:
- path: /tmp/file1
content: "this is file1\n"
directories:
- path: /tmp/dir1
users:
user1:
passwd: password
commands:
- |
bash -x >> /tmp/log 2>&1 <<'EOF'
ls -lFd /tmp/env_file1
printenv ENV1
ls -lFd /tmp/file1
ls -lFd /tmp/dir1
id user1
EOF
You might expect that when the commands get executed, all things defined above it has been executed, such as the user1 has been created.
But it is not. As of now, the output (/tmp/log) is:
+ ls -lFd /tmp/env_file1
ls: cannot access '/tmp/env_file1': No such file or directory
+ printenv ENV1
this is ENV1
+ ls -lFd /tmp/file1
---------- 1 root root 14 Aug 6 07:13 /tmp/file1
+ ls -lFd /tmp/dir1
d--------- 2 root root 40 Aug 6 07:13 /tmp/dir1/
+ id user1
id: ‘user1’: no such user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi!
The execution order of steps in a stage is defined here. This means that the files(EnsureFiles plugin) is always executed before the commands plugin for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fferrann @m-ildefons Thanks for pointing out the ref. Yes, I know where is the definition, but most users don't have time to check source code for such things. And there is no obvious logical reason that why it is implemented in such a way, it is just happened to be that order. So I think the document should explicitly tell users about the order is not like what they might think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The order might change in the future, such as when adding a new substeps, then where is should be put? and who is going to determine the order? Who can know the order just by the substep name without thinking deeply or checking source code?
| Therefore, when you have multiple `substeps` that related to each other, please do not define them in a single `step`. | ||
| Instead, you can split the `substeps` into multiple `steps` which are ensured to be executed by the definition order. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO this is pretty hard to understand. An example would help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated with an example. https://github.com/rancher/elemental-toolkit/pull/2294/files#r2256131749
|
@m-ildefons Thank you so much for taking a look into this. I will modify the document. Your comments are very helpful. |
0fa17c0 to
9f21fa8
Compare
|
I have updated some description. |
| ``` | ||
|
|
||
| You might expect that when the `commands` get executed, all things defined above it has been executed, such as the user1 has been created. | ||
| But it is not. As of now, the output (/tmp/log) is: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mark
frelon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments, also I would remove any mention of substeps, yip works using stages and steps.
| EOF | ||
| ``` | ||
|
|
||
| You might expect that when the `commands` get executed, all things defined above it has been executed, such as the user1 has been created. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As described before the execution ordering is specified when loading the plugins in
| executor.WithPlugins( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me add the reference to the document. Welcome to correct me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ``` | ||
|
|
||
| The internal order is depending on the implementation, see https://github.com/rancher/elemental-toolkit/blob/d8450e01b9119b76670421880070d2cc7fa5f936/pkg/cloudinit/cloudinit.go#L52. | ||
| You can see that the `plugins.User` is behind `plugins.Commands`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mark
b58c393 to
05167d0
Compare
| ls -lFd /tmp/file1 | ||
| ls -lFd /tmp/dir1 | ||
| id user1 | ||
| EOF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mark. See above "step1" and "step2". Multiple steps defined in a stage will be executed by the definition order,
but inside each step, there are multiple plugin in it, such as files, 'commands`, what should we call them? @frelon
@frelon Welcome to give it a better name. What would you call the properties under same step? Could you please check https://github.com/rancher/elemental-toolkit/pull/2294/files#r2256228693 ? |
… and substeps Signed-off-by: jjqq2013 <[email protected]>

Just fix typos, add some explanation about execution order of Cloud-init files, steps, and substeps, which are not that obvious to users.