【问题标题】:Use a Chef recipe to modify a single line in a config file使用 Chef 配方修改配置文件中的单行
【发布时间】:2016-07-07 09:14:51
【问题描述】:

我正在尝试使用 Chef Recipe 自动禁用 MongoDB 的透明大页面 (THP) 设置。

此处解释了 THP 设置:MongoDocs THP Settings

我正在尝试通过编辑“/etc/grub.conf”中的 grub 配置文件来遵循第一个选项“在启动时配置(首选)”

我需要做的就是将“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>) 

其中&lt;lines&gt; = 文件路径、= Chef::Util::FileEdit.new() 和 = 'test string',但似乎没有任何效果。

有人对 Chef::Util::Editor 有任何经验吗?还是更好的解决方案?

谢谢

【问题讨论】:

  • 文件是静态的,还是有其他可能是动态的配置?如果它们的文件是静态的,那么您可以将配置文件添加到说明书的文件中,然后使用 cookbook_file 指令替换以前的配置文件。
  • 自从这个问题被打开以来已经有一段时间了。你有想过解决办法吗?
  • @spuder 我从来没有想过如何用厨师修改配置文件中的一行。希望我是一名主厨,但我很确定我仍然只是在做菜坑。如果您尝试禁用 MongoDB 的 THP 设置,我发布了我最终所做的作为答案。

标签: mongodb chef-infra


【解决方案1】:

我从未想过如何使用 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)
# http://stackoverflow.com/questions/7948789/mongodb-mongod-complains-that-there-is-no-data-db-folder
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,那么你的修改将会丢失。
  • 为什么要使用 tee 和 append?只回显从不到文件还不够吗?
【解决方案2】:

您自己的解决方案的问题是模板可以被另一个具有自己的 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 确保该行不在其中。

也许厨师有更好的办法来管理它?

【讨论】:

    【解决方案3】:

    我们可以通过对元素进行分组来有效地替换文件内容

    例如 将“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.*/, '\0 tansparent_hugepage=never')
        file.write_file
      end
    end
    

    \0 添加整个匹配的字符串

    注意:' '(单引号)

    【讨论】:

      【解决方案4】:

      我通过在 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(regex, newline) ⇒ 对象

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-30
        • 2014-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多