【问题标题】:How to declare particular line in file (/etc/fstab) with Augeas?如何使用 Augeas 在文件 (/etc/fstab) 中声明特定行?
【发布时间】:2015-02-19 13:25:29
【问题描述】:

我正在尝试使用 Augeas 来声明/确保 fstab 中存在特定的挂载点。如果它已经存在,请确保它具有这些 $settings,否则创建一个新行。

但我还没有能够做到这一点。我可以让它修改现有的行,我可以让它添加一个新行。但不是both,如(伪代码):

if (line_exists) {
    check_and_modify_line()
} else {
    create_new_line()
}

check_and_modify_line(),这行得通:

set /files/etc/fstab/*[file="/mnt/ISO"]/file "/mnt/ISO"
set /files/etc/fstab/*[file="/mnt/ISO"]/spec "nas:/ISO/iso"
set /files/etc/fstab/*[file="/mnt/ISO"]/vfstype "nfs"
set /files/etc/fstab/*[file="/mnt/ISO"]/opt "intr"
set /files/etc/fstab/*[file="/mnt/ISO"]/dump "0"
set /files/etc/fstab/*[file="/mnt/ISO"]/passno "0"

create_new_line(),这行得通:

set /files/etc/fstab/01/spec "nas:/ISO/iso"
set /files/etc/fstab/01/file "/mnt/ISO"
set /files/etc/fstab/01/vfstype "nfs"
set /files/etc/fstab/01/opt[1] "intr"
set /files/etc/fstab/01/dump "0"
set /files/etc/fstab/01/passno "0"

但是将上述两个部分组合成一个部分的秘诀让我难以理解。而且我认为 Augeas 应该是声明式/幂等的,所以我不能告诉 Augeas:“确保这条线存在”,这让我很惊讶。

似乎也没有任何 if/then/else 样式块,因为那样我可以:

if match /files/etc/fstab/*[file="/mnt/ISO"]
    defnode isonode /files/etc/fstab/*[file="/mnt/ISO"]
else
    defnode isonode /files/etc/fstab/01

set $isnode/file "/mnt/ISO"
set $isnode/bla "bla-bla"

有没有办法在一组“设置”操作或单个 .aug 文件中完成这一切,所以我可以运行一个:

sudo augtool < mountpoint.aug

当然,我可以使用一对互斥onlyif-s 的 augeas puppet 资源,或者一个包装器,例如在 bash 或 perl 中结合 grep、sed 等,但我不妨坚持完全使用它而不是 Augeas...

顺便说一句,使用Augeas 的官方文档是否比小tour 更全面?整个documentation 似乎是专门为新镜头开发人员 提供的,而不是为可能更多的镜头用户

【问题讨论】:

    标签: augeas


    【解决方案1】:

    如果您不想为条件句使用高级语言(C、ruby、perl、php 等),您可以使用defvar 来达到此目的:

    #!/usr/bin/augtool -Asf
    
    # The -A combined with this makes things much faster
    # by loading only the required lens/file
    transform Fstab.lns incl /etc/fstab
    load
    
    # $noentry will match /files/etc/fstab only if the entry isn't there yet
    defvar noentry /files/etc/fstab[count(*[file="/mnt/ISO"])=0]
    
    # Create the entry if it's missing
    set $noentry/01/spec "nas:/ISO/iso"
    set $noentry/01/file "/mnt/ISO"
    
    # Now amend existing entry or finish creating the missing one
    defvar entry /files/etc/fstab/*[file="/mnt/ISO"]
    
    set $entry/spec "nas:/ISO/iso"
    set $entry/vfstype "nfs"
    set $entry/opt "intr"
    set $entry/dump "0"
    set $entry/passno "0"
    

    请注意,我目前正在致力于在 Augeas 中支持 Lua(请参阅 https://github.com/hercules-team/augeas/pull/300),因此 下一个版本 可能会允许编写类似这样的内容(尽管语法可能仍然改变):

    #!/usr/bin/augtool -lAsf
    --- pass the spec as spec=<spec>
    --- pass the file as mount=<mount>
    
    spec = os.getenv("spec")
    mount = os.getenv("mount")
    
    transform("Fstab.lns", "/etc/fstab", false)
    load()
    
    file_path = "etc/fstab/*[file='" .. mount .. "']"
    if (aug_matches(file_path) == 0) then
      defnode("file", "etc/fstab/01", nil)
      set("$file/spec", spec)
      set("$file/file", mount)
    else
      defvar("file", file_path)
    end
    
    set("$file/spec", spec)
    set("$file/vfstype", "nfs")
    set("$file/opt", "intr")
    set("$file/dump", "0")
    set("$file/passno", "0")
    

    然后可以称为:

    mount=/mnt/ISO spec=nas:/ISO/iso ./aug.lua
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-28
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多