0

I'm trying to use Augeas to declare/ensure that a particular mount point exists in fstab. If it already is there, make sure it has these $settings, otherwise create a new line that does.

But I haven't been able to get augeas to do that. I can get it to modify an existing line and I can get it add a new line. But not both, as in (pseudocode):

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

To check_and_modify_line(), this works:

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"

To create_new_line(), this works:

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"

But the secret sauce that combines the above two sections into a single one eludes me. And I thought that Augeas was supposed to be declarative/idempotent, so it surprises me quite a lot that I can't tell Augeas: "Make sure this line exists".

There also don't seem to be any if/then/else style blocks, because then I could:

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"

Is there a way to do this all in a single bunch of "set" operations or a single .aug file, so I can run a single:

sudo augtool < mountpoint.aug

Sure I could use a couple of augeas puppet resources with mutually exclusive onlyif-s, or a wrapper e.g. in bash or perl with some combination of grep, sed etc. but then I might as well stick to using that completely and not Augeas...

By the way, is there more comprehensive official documentation for using Augeas than the tiny tour? The entire documentation seems to be dedicated to new lens developers, not for the presumably more numberous lens users.

Peter V. Mørch
  • 13,830
  • 8
  • 69
  • 103

1 Answers1

0

If you don't want to make use of a higher level language (C, ruby, perl, php, etc.) for the conditionals, what you can do is use defvar for that purpose:

#!/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"

As a note, I'm currently working on Lua support in Augeas (see https://github.com/hercules-team/augeas/pull/300), so it's likely that the next release will allow to write something like this (although the syntax might still change):

#!/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")

which can then be called as:

mount=/mnt/ISO spec=nas:/ISO/iso ./aug.lua
raphink
  • 3,625
  • 1
  • 28
  • 39
  • The first example made sense after reading https://github.com/hercules-team/augeas/wiki/Path-expressions and trying it out in the interactive `augtool`. However, the variable `noentry` is poorly named. It would be better called `conditional_base`. (is may or may not be (as appropriate) the file to work on (`fstab` it this case). – ctrl-alt-delor Jul 25 '22 at 10:31