[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Mon, 19 Jan 2004 17:21:16 +1100 (EST)
Hi all. We have about 80 different kinds of functions in the
editfiles section, and often there are groups that do similar things. I
was windering if we could have a bit of a think, and see if we couldn't
come up with a better way of doing things, ie. performing the same
functions without having to remember 80 or so different commands.
The first thing I noticed was how many of these commands were
based around IF x DO y. My suggestion would be to have an IF ... DO
structure (only in editfiles, of course). However, the <condition> will
sometimes need to access the parameters of the <action>, and vice versa, I
think. Also, where I specify a field # in the action, it means the action
is done to that field # instead of the whole line.
IF [No(t)] <condition> [Parameters] DO <action> [Parameters]
AnyLineMatches [ regex <regex> ]
ThisLineMatches [ regex <regex> ]
FieldMatches [ regex ] <regex> <field#>
LineNumber <line #>
Append <string> [ <field#> ]
BeginGroup ... EndGroup
Comment [ <commentchar> ]
Define [ InGroup ] <classes>
For <iterator> <action>
Can be used to replace eg. CommentNLines. Can contain a
(unfortunately this requires that conditions be settable,
and it's up to cfengine to figure out how to make them
true, but it's easy enough for things like LastLine)
Prepend <string> [ <field#> ]
ReplaceWith <string> [ <field#> ]
Set [ InGroup ] <editvar> <value>
UnComment [ <commentchar> ]
ReplaceAll quoted-regex With quoted-string
Ok, so assuming we were to follow my advice, we'd now have 8
conditions, 33 commands, 9 variables which can be set with the Set
command, and 3 iterators (for use with "For"). Which is still 53 things
to remember. Not a big improvement over 80, you might think. But the
difference is, these 53 things can be combined to produce the equivalent
of 264 possible commands (and that's not counting editvars or iterators).
So 53 is a big reduction from 264+, at least to my mind.
Additionally, say someone says "hey, we need a
RemovePorridgeIfAlmostMatches function". Rather than writing a
function with that name, they'd write two functions, RemovePorridge, and
AlmostMatches. That way, we'd be able to use:
IF Not AlmostMatches DO Append "/etc/fstab"
And no-one would have to write the AppendIfAlmostMatches function.
It would also mean that I'd have my:
IF FieldMatches "/home" 2 DO Append ",nosuid,nodev" 4
(IF Field 2 matches "/home" DO Append ",nosuid,nodev" to field 4). Yeah,
sure, this looks a bit more complex, but the alternative would be
AppendToFieldIfOtherFieldMatches "/home" 2 ",nosuid,nodev" 4
-- which is even worse
Or, to give you a more familar example (using /etc/sysctl.conf),
AppendIfNoSuchLine "net.ipv4.ip_forward = 0"
IF Not AnyLineMatches DO Append "net.ipv4.ip_forward = 0"
Of course, this is an example where the condition has to access
the parameters of the action.
The editfiles section could also be turned into a separate
language as someone on the mailing list suggested some time ago.
Possible objections answered:
- It's less powerful
I believe I've duplicated all existing functionality here, and
with very little loss of readability for the power gained. If
you think otherwise, feel free to give me an example.
- It's not the cfengine way (contains IF statements)
Actually, it's pretty much identical to the current situation.
Look at how many of the current editfiles commands already contain
the word "if". They're basically if statements in disguise.
*However,* they're not your standard IF statements (either way) --
they often contain iterators (cf. AnyLineMatches) or other
powerful functionality under the hood (all of which I want to
Anyway, hope this is useful to how cfengine works, and means that
we don't have to add all of those 264 functions that I mentioned.
Also, I by no means think that my idea is the be-all and end-all
of solutions. I guess I was hoping to promote discussion of an area where
I think cfengine needs some work.
Tel: +61 3 5241 1155
Fax: +61 3 5241 6187