![如何将参数从 PXE 命令行传递到 kickstart %pre、%post 脚本?](https://linux22.com/image/579718/%E5%A6%82%E4%BD%95%E5%B0%86%E5%8F%82%E6%95%B0%E4%BB%8E%20PXE%20%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%BC%A0%E9%80%92%E5%88%B0%20kickstart%20%25pre%E3%80%81%25post%20%E8%84%9A%E6%9C%AC%EF%BC%9F.png)
基本上,我想要在 PXE 命令行上使用类似 ARGV 的用法,但我看不到任何有关执行此操作的文档。
基本上我想传递类似的东西
scientific-linux-6 主机名 VLAN
然后在 %pre 中调用一些 API 来获取我需要的网络信息,并将其附加到 KS 配置中。如果我有参数,这部分就很简单。
最后,在 %post 中,我想启动 chef 运行并引导到 chef 服务器。这还需要知道主机名/域名(基本上有 hostname -f 不会爆炸),但如果我能完成上述操作,这应该不会太糟糕。遗憾的是,这是我最初的目标,但当我意识到我还没有设置主机名时,它失败了。
以下是我目前所学到的知识。
$ cat linux-install/msgs/param.msg
09Kernel Parameter Help07
Some kernel parameters can be specified on the command line and will be
passed to the running kernel. This does not include options to modules
such as ethernet cards or devices such as CD-ROM drives.
To pass an option to the kernel, use the following format:
0flinux <options>07
If a different installation mode is desired, enter it after the option(s).
For example, to install on a system with 128MB of RAM using expert mode,
type the following:
0flinux mem=128M expert07
To pass options to modules, you will need to use the expert mode to disable
PCI autoprobing. When the installation asks for your device type that needs
an option or parameter passed to it, there will be a place to type those
in at that time.
太棒了!?这意味着在 PXE 上我可以这样做……
scientific-linux-6 linux ARGV_APPEND
正确的?
然后把内容放入 %pre 和 %post 我发现本演讲和其他一些提及
Stick this at the top of the %pre section, and it will take anything of the form var=value
from /proc/cmdline and turn it into a variable you can use directly
set -- `cat /proc/cmdline`
for I in $*; do case "$I" in *=*) eval $I;; esac; done
所以这意味着我可以说
scientific-linux-6 linux HOSTNAME=foo.example.com, VLAN=ddd
正确的?
然后在 %pre 这意味着我可以
点击我的 API 来获取 IP、掩码、网关,然后将网络更改为类似
network --bootproto=static --ip=10.0.2.15 --netmask=255.255.255.0
--gateway=10.0.2.254 --nameserver=10.0.2.1
正如所描述的这里
然后这会在 %post 中为我们设置 chef-client 运行。
我的问题是。这听起来可行吗?还有更好的方法吗?肯定有人以前这样做过吧?
更新(根据答案实施的解决方案)
在 PXE 命令行上,我最终传递了选项
$ hotbox linux prefix_varname="foo" prefix_another_var="bar"
(之后的所有内容linux
都放在 /proc/cmdline 上。hotbox
是 PXE 标签。)然后%post
我解析了 /proc/cmdline(在 Ruby 中),寻找所有与 /prefix_*/ 匹配的变量并将它们转换为哈希值。这导致根据 Web 请求的结果将其传递给 chef 进行进一步配置。
注意:当我做这些的时候,Razor 还没有出现。我个人对 Razor 并不满意,我们仍然或多或少地使用上述方法。
答案1
对于简单的布尔选项,我已经grep
在 中完成了一个/proc/cmdline
,这很容易。对于键值选项,这个set
技巧似乎很方便,尽管我还没有尝试过。具体回答您的问题:
1) 是的,听起来这可行。我用 kickstart 和 做过类似的事情/proc/cmdline
。
2) 不,我认为没有更好的方法。内核在 中公开了它的命令行选项/proc/cmdline
,而 kickstart 没有提供任何处理内核命令行选项的高级机制。
3) 是的,以前有人这样做过。尝试一下,如果做不到就再回来。
一些额外的想法:
1)不要在命令行选项之间加逗号(只需用空格分隔)。
2) 使用 pxelinux 时,使用一行会很有帮助append
。例如:
append initrd=f16-x86_64/initrd.img ks=nfs:server.example.com:/path/to/f16.ks mycustomflag mykey=myval
3)网络设置(如您提供的主机名示例)通常更适合使用 DHCP。
答案2
我能够使用以下命令将所有键值对解析为变量来使其工作:
# Get the kernel parameters
params=`cat /proc/cmdline`
# Split them on spaces
params_split=(${params// / })
# Go through each of them
for p in "${params_split[@]}"; do
# And if it's a key value pair
if [[ $p =~ "=" ]]; then
# And if the key doesn't have a period in it
p_split=(${p//=/ })
if [[ !($p_split[0] =~ ".") ]]; then
# Then set the key to the value
eval $p;
fi;
fi
done
答案3
那应该是
if [[ ! ($p_split[0] =~ ".") ]]; then
^^^
你可能想用以下代码包围它:
#raw
...
#end raw
因此 cobbler/cheetah 模板插值不会出现问题。