clearlinux / micro-config-drive

An alternative and small cloud-init implementation in C
Other
45 stars 17 forks source link

runcmd directive incorrectly interprets list items #49

Open jakub-d opened 4 years ago

jakub-d commented 4 years ago

According to the original documentation of the cloud-config: https://cloudinit.readthedocs.io/en/latest/topics/examples.html#run-commands-on-first-boot

"if the item is a list, the items will be properly executed as if passed to execve(3) (with the first arg as the command)."

In micro-config-drive, the lists are simply joined into one command and executed by shell:

#cloud-config
---

preserve_hostname: true

runcmd:
  - ls
  - ps
  - whoami
  - [ ls, -l, /tmp ]

There should be 4 commands executed. 3 in shell, 1 using execve(3) call. The last one instead of execve is executed in shell.

ucd[626]: [4.289228] lib: Executing: /bin/sh -c "ls -l /tmp "
ahkok commented 4 years ago

Seems a duplicate of #29?

ahkok commented 4 years ago

Note: while we attempted to implement the standard, we make no guarantee that the implementation is 100% standards compliant. So we may not close this item. In this case, there's some parser specific issue going on that makes it more complex.

jakub-d commented 4 years ago

Seems a duplicate of #29?

Not really. There are 3 problems with the runcmd. I will describe them on one configuration example:

runcmd:
  - command1  arg1
  - command2 arg2
  - [ command3, arg3 ]
  - [ command4,  arg4 ]

Problem one (described in #29): The order of the list in the runcmd is not preserved.

It should run: command3 arg3 command4 arg4 It runs (sometimes in this order, and there is no guarantee): command4 arg4 command3 arg3

Problem two (described in this issue): When the runcmd is the list item, it should be executed by the excve. It should run: execve(command3, arg3) execve(command4, arg4) It runs /bin/sh -c command3 arg3 and /bin/sh -c command4 arg4.

Problem three (described in #48): It should run: /bin/sh -c command1 arg1 /bin/sh -c command2 arg2 it runs: /bin/sh -c command 1 arg1 command2 arg2

ahkok commented 4 years ago

Yeah, this has been a long-standing problem.

ahkok commented 4 years ago

FWIW I've spent several days looking into whether our use of the YAML parser library and glib node tree is deficient and I have not yet identified an actual solution that would work. The issue is highly complex because of the way that YAML presents lists and some of the finesses of how you can write lists in YAML do not properly translate to what you think they do.

Any potential changes I've identified would break existing modules. I have yet to identify a solution in code that would actually improve things here.