Environment queries, and objects with constructors
Why can't I require libraries in a policy file? I need to be able to query my environment to figure out how modules should be called. Is there another way? Also, it would be nice if modules could expose constructors.
The environment of the policy is sandboxed. Incidentally was contemplating on user provided modules. Just added it to the Todo project, I'll work on that after polishing the dependency support.
What do you mean by constructors?
Just curious. Which Linux flavor/distro are you using Configi for?
What do you mean by constructors?
So modules take config as an object {a=b, ...}, but sometimes you have a bunch of complicated options that describe one "thing", that are being passed to multiple modules. Having an object that you pass around is easy to do in the policy file, but having a constructor that creates an object, fills in some defaults, queries the system to fill in other details, and provides useful methods is better.
For example, when I write git policies in CFEngine, I end up typing out the same arguments over and over (user, group, umask, root path, worktree path, remote, etc.). I also end up writing system queries over and over to set classes/booleans based on that "object", or to figure out properties of it. Something like this would be much nicer:
local gitobj = require "gitobj"
local myrepo = gitobj.root{
user="eric",
umask="0022",
directory="/home/eric/myrepo"
}
-- the constructor has a prototype with methods on it...
for dir in myrepo:workdirs() do
-- now use the existing module system to assert some things about those directories...
git.filesCheckedIn("auto checkin..."){workdir = dir, repo = myrepo}
link.symlink{source = join("/home/eric/gitdirs/", canonicalize(dir)), target = dir}
end
Here's a concrete example of the repetition I'm trying to avoid: https://gist.github.com/oconnore/c4c83b5c445b14a223779cdc67b2f43f#file-example-cf-L40-L84
Also, speaking of booleans, I see that factid will be sort of like CFEngine hard classes, do you have plans for user provided "soft classes"?
Just curious. Which Linux flavor/distro are you using Configi for?
Well, I typically run CentOS/Fedora as a base system, with Nix installing packages to ~/.nix-profile/, although my laptop has Ubuntu on it. All of that is currently CFEngine managed, but I'm sick of hacking classes + shell scripts + normal ordering to do what I want.
Thanks Eric,
That gitobj example is very doable with user provided modules. Also possible with core modules but it will be trickier to figure out the methods and not overdo it.
As for soft classes, you can just add or clobber a table in fact or use plain variables.
module"fact"
fact.myclass = {}
fact.myclass.whatever = true
myfact = true
file.touch "/tmp/test" {
comment = "Only executed if context is true",
context = fact.myclass.whatever
}
file.touch "/tmp/test" {
contex = myfact
}
That gitobj example is very doable with user provided modules. Also possible with core modules but it will be trickier to figure out the methods and not overdo it.
Cool! I'll look forward to seeing how user modules work. Let me know if you have a small-ish part of the project that I could help with. I am sort of new to Lua, but I used to write Javascript (prototypes!), so I'm picking it up ok.
I'll play with FactId to get the hang of it, that's pretty neat. How is FactId different than just exposing a Lua table?
Do you have ideas for new core modules? That would be fantastic.
Factid is just a table with 'facts' in it. The default is not to load it.
Finally implemented user provided modules.
User modules are under the modules/ directory in the same path as the main policy.
For example if passing a /tmp/test.lua policy then modules are in /tmp/modules. You can override core modules since that is searched first.
See test/core-user-modules for a working example.