Customised machine: curtin_userdata script not executed as expected

Bug #2065861 reported by maasuser1
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
MAAS
Invalid
Undecided
Unassigned

Bug Description

As shown in the picture, the log looks weird, and the change has not been applied.

```yaml
#cloud-config
debconf_selections:
 maas: |
  {{for line in str(curtin_preseed).splitlines()}}
  {{line}}
  {{endfor}}

late_commands:
 maas: [wget, '--no-proxy', '{{node_disable_pxe_url}}', '--post-data', '{{node_disable_pxe_data}}', '-O', '/dev/null']
 10_motd_template: |
  curl 'URL to gist' -o /etc/motd
  sed -i "s/{hostname}/$(hostname)/g" /etc/motd
```

MAAS 3.4/Stable

Thanks!

Revision history for this message
maasuser1 (maasuser1) wrote :
Revision history for this message
Anton Troyanov (troyanov) wrote :

Hi maasuser1,

I am not super familiar with curtin, but I can see that all the commands [0] are passed as a list, not as a multiline string.

May I ask you to try representing your commands as a list instead?
Something like this or similar:

```
late_commands:
  10_motd_save : [curl, 'URL to gist','-o', '/etc/motd']
  10_motd_replace : [sed, '-i','"s/{hostname}/$(hostname)/g"', '/etc/motd']
```

[0]: https://curtin.readthedocs.io/en/latest/topics/config.html#stages

Changed in maas:
status: New → Incomplete
Revision history for this message
maasuser1 (maasuser1) wrote :

Thanks Anton. May I ask how to represent pipeline operators `>` `<` in the list?

Revision history for this message
Anton Troyanov (troyanov) wrote :

Hmm, I was wrong about list/multiline. This documentation [0] has several examples with a multiline string

```
debconf_selections:
  set1: |
   cloud-init cloud-init/datasources multiselect MAAS
   lxd lxd/bridge-name string lxdbr0
set2: lxd lxd/setup-bridge boolean true
```

[0]: https://readthedocs.org/projects/curtin/downloads/pdf/latest/

Revision history for this message
Anton Troyanov (troyanov) wrote :

maasuser1, may I ask you to try running your command defined as list?

Changed in maas:
status: Incomplete → New
status: New → Incomplete
Revision history for this message
maasuser1 (maasuser1) wrote :

I revised my command into one line:

```yaml
10_motd_template: [curl, '{redacted_url}', '-o', '/etc/motd']
```

```log
 Tue, 21 May. 2024 14:21:04 Node installation - 'curtin' running 'curl {redacted_url} -o /etc/motd'
```

The log shows above, but the `/etc/motd` file does not exist after deployed.

Revision history for this message
Javier Fuentes (javier-fs) wrote :

Hi maasuser1,

If you want to create and update a file during deployment with the purpose of using it later, you could directly use cloud-init syntax.

```
#cloud-config

runcmd:
  - [curl, "https://example.com/", --output, /etc/motd]
  - [sed, -i, -e, "s/Example/Test/g", /etc/motd]

```

If you would like to use the most recent version of the template, maybe `bootcmd` is a better fit. It is similar to `runcmd` but runs the commands in every boot.

Additionally, you could also download the template using `write_files`:
- https://curtin.readthedocs.io/en/latest/topics/config.html#write-files
- https://cloudinit.readthedocs.io/en/latest/reference/examples.html#writing-out-arbitrary-files
and modify it later with `bootcmd`.

Revision history for this message
maasuser1 (maasuser1) wrote :

Thank you Javier.

https://maas.io/docs/about-deploying-machines

According to the deployment process, cloud-init script must be uploaded during provisioning, but Curtin scripts will be populated by MAAS automatically.

Revision history for this message
Javier Fuentes (javier-fs) wrote (last edit ):

I see your point.

If I understandand correctly:
- when you run a configuration you can deploy successfully a machine, i.e. the machine will end up in the "deployed" state
- the purpose of the configuration file is to download and customise a template file
- you would like that the customised template is available after the machine has been deployed
- the customised template is not used during the deployment process, but once the machine is deployed
- you are using the preseed files to create your own curtin configuration (https://maas.io/docs/how-to-customise-machines#pre-seed-cloud-init-2)
- you would like to use curtin so you do not have to upload the cloud-init configuration every time that you want to deploy a machine (https://maas.io/docs/how-to-customise-machines#pre-seed-cloud-init-2)

Correct me if any of my previous assumptions is wrong.

Revision history for this message
maasuser1 (maasuser1) wrote :

That's right!

I wanna set default settings like [SSH CA](https://www.lorier.net/docs/ssh-ca.html), MOTD (message of today), admin pubkey ...etc for all future deployed machines. Cloud-init requires manual involvement, while Curtin is finished in a one-go.

Revision history for this message
Javier Fuentes (javier-fs) wrote (last edit ):

Could you try this config file (preseeds/curtin_userdata) and deploy a machine?

```
#cloud-config
debconf_selections:
  maas: |
    {{for line in str(curtin_preseed).splitlines()}}
    {{line}}
    {{endfor}}

late_commands:
  maas: [wget, '--no-proxy', '{{node_disable_pxe_url}}', '--post-data', '{{node_disable_pxe_data}}', '-O', '/dev/null']
  10_example_download: ['curtin', 'in-target', '--', 'wget', 'https://example.com/', '-O', '/etc/example.html']
  11_example_modify: ['curtin', 'in-target', '--', 'sed', '-i', '-e', 's/Example/Test/g', '/etc/example.html']
```

You should find the modified file (/etc/example.html) in the deployed machine.

If you want to add a customised configuration for your machine, you should let curtin know that the command will run in the target. Use "curtin in-target --" followed by the command that you want to run.

Additionally, something that can be useful is to use the endpoint `GET /MAAS/api/2.0/machines/{system_id}/op-get_curtin_config` to see the rendered curtin config file. That can help you to identify any problem during rendering.

Revision history for this message
maasuser1 (maasuser1) wrote :

Thank you, Javier, your script ran as expected. My mistake was that I didn't read the [manual](https://maas.io/docs/how-to-customise-machines) in detail.

Many thanks!

Changed in maas:
status: Incomplete → Invalid
Revision history for this message
maasuser1 (maasuser1) wrote :

Template string does not work with Curtin:

```yaml
11_example_modify: ['curtin', 'in-target', '--', 'sed', '-i', '-e', 's/{hostname}/$(hostname)/g', '/etc/motd']
```

I eventually got "... $(hostname) ..." as a result, instead of "... MyMachine ...".

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.