As you might already know the community version of Cfengine 3 is not able to set ACLs the “Cfengine 3 way”. So when you are using the community edition of Cfengine 3 you have to find another way of doing it.. such as running shell commands out of the Cfengine 3 scripts. I hope the [...]
As you might already know the community version of Cfengine 3 is not able to set ACLs the “Cfengine 3 way”. So when you are using the community edition of Cfengine 3 you have to find another way of doing it.. such as running shell commands out of the Cfengine 3 scripts.
I hope the guys from the Cfengine office won’t be angry with me when I show you a simple example of how setting ACLs with the community edition.
Writing the Cfengine 3 code for setting ACLs on multiple directories
body common control {
version => "1.0";
inputs => { "cfengine_stdlib.cf" };
bundlesequence => { "set_acls" };
}
bundle agent set_acls {
vars:
"shared_directories" slist => { "/home/shared", "/home/archive" };
files:
"$(shared_directories)/."
create => "true";
commands:
"/usr/bin/setfacl -m u:backup:rwx,g:games:rwx ${shared_directories}"
comment => "Setting ACLs on the shared directories.";
}
Check the code snippet for errors. If no warning or error message occurs you should be safe running the script (make sure that /home is mounted with ACL support):
/var/cfengine/bin/cf-promises -f /etc/cfengine3/example12.cf /var/cfengine/bin/cf-agent -f /etc/cfengine3/example12.cf
Now have a look at the two directories:
mintbox / # getfacl /home/shared/ getfacl: Removing leading '/' from absolute path names # file: home/shared/ # owner: root # group: root user::rwx user:backup:rwx group::r-x group:games:rwx mask::rwx other::r-x mintbox / # getfacl /home/archive/ getfacl: Removing leading '/' from absolute path names # file: home/archive/ # owner: root # group: root user::rwx user:backup:rwx group::r-x group:games:rwx mask::rwx other::r-x
Wohoo! Cfengine 3 has just set the requested ACLs on the supplied directories.
Analyzing the Cfengine 3 code snippet
I guess you are already familiar with the meaning of the “body common control” section, so let’s jump to the interesting part:
bundle agent set_acls {
vars:
"shared_directories" slist => { "/home/shared", "/home/archive" };
In the code excerpt above a promise of the type “vars” was created. It contains the promiser “shared_directories” which is a variable of the type “slist”. A slist can contain multiple values and we already make use of this feature here: Our varliable “shared_directories” encapsulates two directories which will be used later for our setfacl command.
Which leads us to the next part…
files:
"$(shared_directories)/."
create => "true";
…where the promise of the type “files” is equipped with the content of the variable “shared_directories” we defined above. As you might have already guessed, Cfengine 3 is iterating through slist until the end of the list is reached. So the statement we perform for the “files” promise will be applied on each item in the slist “shared_directories”. In this case Cfengine 3 makes sure that each directory exists before the ACLs are set.
Please note the “/.” part in this snippet – it is necessary for telling Cfengine 3 that we are dealing with directories and not files.
Now the most important part:
commands:
"/usr/bin/setfacl -m u:backup:rwx,g:games:rwx ${shared_directories}"
comment => "Setting ACLs on the shared directories.";
}
Here a new promise of the type “commands” is defined. It contains a setfacl command which will be issued on each entry of the “shared_list” variable.
Please note that “shared_directories” string is encapsulated in round brackets at the “files” promise. In the “commands” promise the shell command is enhanced by the “shared_directories” slist with curly braces.
Summary
In the code snippet above we first define a list of directories. Afterwards a file promise iterates through the single entries and makes sure that all directories exist before the command promise sets the requested ACLs.
I think that this is a great example for how variables can be used within multiple promises. Furthermore we are able to set ACLs although we do not have Cfengine 3 Nova installed.
As usual, you can download todays’s Cfengine 3 code snippet here.

Comments on this entry (no comments)
Did you like this post? You can share your opinion with us! Simply click here.