通过 cloud-init 运行命令时出现问题

zep*_*oth 3 cloud-init multipass

我正在从事的一个开源项目包含需要 Linux 的组件,因此虚拟化通常是开发和测试新功能的最佳解决方案。我正在尝试为 Multipass 提供一个简单的 cloud-init 文件,该文件将通过从 Git 提取文件并自动在 VM 中设置它们来使用我们的代码配置 VM。然而,即使启动花费的额外时间似乎表明进程正在运行,但似乎没有文件实际保存到主目录中,即使对于更简单的情况也是如此,即

runcmd:
  - [ cd, ~ ]
  - [ touch test ]
  - [ echo 'test' > test ]
Run Code Online (Sandbox Code Playgroud)

我只是错误配置了 cloud-init 还是我错过了一些重要的东西?

lar*_*sks 8

这里有几个问题。

首先,您的云配置用户数据必须以以下行开头:

#cloud-config
Run Code Online (Sandbox Code Playgroud)

如果没有这条线,cloud-init 就不知道如何处理它。如果您要提交如下用户数据配置:

#cloud-config
runcmd:
  - [ cd, ~ ]
  - [ touch test ]
  - [ echo 'test' > test ]
Run Code Online (Sandbox Code Playgroud)

您会发现以下错误/var/log/cloud-init-output.log

runcmd.0: ['cd', None] is not valid under any of the given schemas
/var/lib/cloud/instance/scripts/runcmd: 2: cd: can't cd to None
/var/lib/cloud/instance/scripts/runcmd: 3: touch test: not found
/var/lib/cloud/instance/scripts/runcmd: 4: echo 'test' > test: not found
Run Code Online (Sandbox Code Playgroud)

您将在文档中找到这些问题的解决方案,其中包括以下注释runcmd

# run commands
# default: none
# runcmd contains a list of either lists or a string
# each item will be executed in order at rc.local like level with
# output to the console
# - runcmd only runs during the 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).
# - if the item is a string, it will be simply written to the file and
#   will be interpreted by 'sh'
Run Code Online (Sandbox Code Playgroud)

您传递了一个列表列表,因此行为由“*如果该项目是一个列表,则这些项目将被正确执行,就像传递给 execve(3) (使用第一个参数作为命令)”。在这种情况下,~in[cd, ~]没有任何意义——shell 没有执行该命令,因此没有任何内容可以扩展~

后两个命令包含在单个列表项中,并且您的系统上没有名为 或 的touch test命令echo 'test' > test

这里最简单的解决方案是简单地传递一个字符串列表:

#cloud-config
runcmd:
  - cd /root
  - touch test
  - echo 'test' > test
Run Code Online (Sandbox Code Playgroud)

我已将cd ~此处替换为cd /root,因为最好是明确的(并且您知道这些命令无论如何都会运行root)。