使用 Chef 配方修改配置文件中的一行
Use a Chef recipe to modify a single line in a config file
我正在尝试使用 Chef Recipe 为 MongoDB 自动禁用透明大页面 (THP) 设置。
此处解释 THP 设置:MongoDocs THP Settings
我正在尝试通过编辑位于“/etc/grub.conf”的 grub 配置文件来遵循第一个选项 "In Boot-Time Configuration (Preferred)"
我需要做的就是将 "transparent_hugepage=never" 附加到以 "kernel "
开头的现有行的末尾
我知道我可以用 Chef::Util::FileEdit 替换一行,方法如下:
ruby_block "replace_line" do
block do
file = Chef::Util::FileEdit.new("/etc/grub.conf")
file.search_file_replace_line("/kernel/", "kernel <kernel path> <kernel options> transparent_hugepage=never")
file.write_file
end
end
但我需要保留现有的内核路径和内核选项。
我试过 Chef::Util::Editor,但未能成功初始化构造函数。 Chef::Util::FileEdit 是用文件路径初始化的(如上),但是 ruby 文档说 Chef::Util::Editor 是用 "lines" 初始化的。我试过了
lines = Chef::Util::Editor.new(<lines>)
其中 <lines>
= 文件路径,= Chef::Util::FileEdit.new() 和 = 'test string',但似乎没有任何效果。
有人对 Chef::Util::Editor 有任何经验吗?或者更好的解决方案?
谢谢
我从来不知道如何使用 Chef 修改配置文件中的一行,但这是我最终用来禁用 MongoDB.
的 THP 设置的方法
方法:安装 MongoDB
# Install MongoDB on Amazon Linux
# http://docs.mongodb.org/manual/tutorial/install-mongodb-on-amazon/
# 1: configure the package management system (yum)
# 2: install mongodb
# 3: configure mongodb settings
# 3.A: give mongod permission to files
# data & log directories (everything in /srv/mongodb)
#
execute "mongod_permission" do
command "sudo chown -R mongod:mongod /srv/mongodb"
#command "sudo chown mongod:mongod /var/run/mongodb/mongod.pid"
#command "sudo chown -R $USER /srv/mongodb"
end
# 3.B: edit Transparent Huge Pages (THP) Settings
# get rid of mongod startup warning
# http://docs.mongodb.org/manual/reference/transparent-huge-pages/#transparent-huge-pages-thp-settings
# 3.B.1: disable
execute "disable_thp_khugepaged_defrag" do
command "echo 0 | sudo tee /sys/kernel/mm/transparent_hugepage/khugepaged/defrag" # different b/c file doesn't have options list
end
execute "disable_thp_hugepage_defrag" do
command "echo 'never > /sys/kernel/mm/transparent_hugepage/defrag' | sudo tee --append /sys/kernel/mm/transparent_hugepage/defrag"
end
execute "disable_thp_hugepage_enables" do
command "echo 'never > /sys/kernel/mm/transparent_hugepage/enabled' | sudo tee --append /sys/kernel/mm/transparent_hugepage/enabled"
end
# 3.B.2: verify disabled on reboot
template "/etc/rc.local" do
source "init-rc.local.erb"
owner 'root'
group 'root'
mode '0775'
end
# 4: use upstart & monit to keep mongod alive
模板:init-rc.local.erb
touch /var/lock/subsys/local
if test -f /sys/kernel/mm/transparent_hugepage/khugepaged/defrag; then
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
您自己的解决方案的问题是模板可能会被另一个具有自己的 rc.local 模板的食谱覆盖。
要更改它,我将这些行添加到现有 rc.local
execute "disable_thp_hugepage_defrag" do
command "sudo sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/defrag\n' /etc/rc.local"
not_if 'grep -c "transparent_hugepage/defrag" /etc/rc.local'
end
execute "disable_thp_hugepage_enables" do
command "sudo sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/enabled\n' /etc/rc.local"
not_if 'grep -c "transparent_hugepage/enabled" /etc/rc.local'
end
grep
确保该行不在其中。
也许厨师有更好的办法来处理它?
我们可以通过对元素进行分组来高效地替换文件内容
例如
将 "transparent_hugepage=never" 附加到以 "kernel "
开头的现有行的末尾
ruby_block "replace_line" do
block do
file = Chef::Util::FileEdit.new("/etc/grub.conf")
file.search_file_replace_line(/kernel.*/, '[=10=] tansparent_hugepage=never')
file.write_file
end
end
\0 添加完整的 mached 字符串
注意:' '(单引号)
我通过在 chef 中复制以下内容来禁用大页面(看起来与上面相同,但添加了 not_if 语句):
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
E.G
execute "disable_hugepage_defrag" do
not_if "grep -F '[never]' /sys/kernel/mm/transparent_hugepage/defrag"
command "echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag"
end
我也成功地插入了带有 file.insert_line_if_no_match
the ruby line replace feature 的行可能对你有用。
search_file_replace_line(正则表达式,换行符)⇒ 对象
ruby_block 'replace_line' do
block do
file = Chef::Util::FileEdit.new('/path/to/file')
file.search_file_replace_line('/Line to find/', 'Line to replace with')
file.write_file
end
end
我正在尝试使用 Chef Recipe 为 MongoDB 自动禁用透明大页面 (THP) 设置。
此处解释 THP 设置:MongoDocs THP Settings
我正在尝试通过编辑位于“/etc/grub.conf”的 grub 配置文件来遵循第一个选项 "In Boot-Time Configuration (Preferred)"
我需要做的就是将 "transparent_hugepage=never" 附加到以 "kernel "
开头的现有行的末尾我知道我可以用 Chef::Util::FileEdit 替换一行,方法如下:
ruby_block "replace_line" do
block do
file = Chef::Util::FileEdit.new("/etc/grub.conf")
file.search_file_replace_line("/kernel/", "kernel <kernel path> <kernel options> transparent_hugepage=never")
file.write_file
end
end
但我需要保留现有的内核路径和内核选项。
我试过 Chef::Util::Editor,但未能成功初始化构造函数。 Chef::Util::FileEdit 是用文件路径初始化的(如上),但是 ruby 文档说 Chef::Util::Editor 是用 "lines" 初始化的。我试过了
lines = Chef::Util::Editor.new(<lines>)
其中 <lines>
= 文件路径,= Chef::Util::FileEdit.new() 和 = 'test string',但似乎没有任何效果。
有人对 Chef::Util::Editor 有任何经验吗?或者更好的解决方案?
谢谢
我从来不知道如何使用 Chef 修改配置文件中的一行,但这是我最终用来禁用 MongoDB.
的 THP 设置的方法方法:安装 MongoDB
# Install MongoDB on Amazon Linux
# http://docs.mongodb.org/manual/tutorial/install-mongodb-on-amazon/
# 1: configure the package management system (yum)
# 2: install mongodb
# 3: configure mongodb settings
# 3.A: give mongod permission to files
# data & log directories (everything in /srv/mongodb)
#
execute "mongod_permission" do
command "sudo chown -R mongod:mongod /srv/mongodb"
#command "sudo chown mongod:mongod /var/run/mongodb/mongod.pid"
#command "sudo chown -R $USER /srv/mongodb"
end
# 3.B: edit Transparent Huge Pages (THP) Settings
# get rid of mongod startup warning
# http://docs.mongodb.org/manual/reference/transparent-huge-pages/#transparent-huge-pages-thp-settings
# 3.B.1: disable
execute "disable_thp_khugepaged_defrag" do
command "echo 0 | sudo tee /sys/kernel/mm/transparent_hugepage/khugepaged/defrag" # different b/c file doesn't have options list
end
execute "disable_thp_hugepage_defrag" do
command "echo 'never > /sys/kernel/mm/transparent_hugepage/defrag' | sudo tee --append /sys/kernel/mm/transparent_hugepage/defrag"
end
execute "disable_thp_hugepage_enables" do
command "echo 'never > /sys/kernel/mm/transparent_hugepage/enabled' | sudo tee --append /sys/kernel/mm/transparent_hugepage/enabled"
end
# 3.B.2: verify disabled on reboot
template "/etc/rc.local" do
source "init-rc.local.erb"
owner 'root'
group 'root'
mode '0775'
end
# 4: use upstart & monit to keep mongod alive
模板:init-rc.local.erb
touch /var/lock/subsys/local
if test -f /sys/kernel/mm/transparent_hugepage/khugepaged/defrag; then
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
fi
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
您自己的解决方案的问题是模板可能会被另一个具有自己的 rc.local 模板的食谱覆盖。
要更改它,我将这些行添加到现有 rc.local
execute "disable_thp_hugepage_defrag" do
command "sudo sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/defrag\n' /etc/rc.local"
not_if 'grep -c "transparent_hugepage/defrag" /etc/rc.local'
end
execute "disable_thp_hugepage_enables" do
command "sudo sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/enabled\n' /etc/rc.local"
not_if 'grep -c "transparent_hugepage/enabled" /etc/rc.local'
end
grep
确保该行不在其中。
也许厨师有更好的办法来处理它?
我们可以通过对元素进行分组来高效地替换文件内容
例如 将 "transparent_hugepage=never" 附加到以 "kernel "
开头的现有行的末尾ruby_block "replace_line" do
block do
file = Chef::Util::FileEdit.new("/etc/grub.conf")
file.search_file_replace_line(/kernel.*/, '[=10=] tansparent_hugepage=never')
file.write_file
end
end
\0 添加完整的 mached 字符串
注意:' '(单引号)
我通过在 chef 中复制以下内容来禁用大页面(看起来与上面相同,但添加了 not_if 语句):
echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
E.G
execute "disable_hugepage_defrag" do
not_if "grep -F '[never]' /sys/kernel/mm/transparent_hugepage/defrag"
command "echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag"
end
我也成功地插入了带有 file.insert_line_if_no_match
the ruby line replace feature 的行可能对你有用。
search_file_replace_line(正则表达式,换行符)⇒ 对象
ruby_block 'replace_line' do
block do
file = Chef::Util::FileEdit.new('/path/to/file')
file.search_file_replace_line('/Line to find/', 'Line to replace with')
file.write_file
end
end