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 [...]

Author:

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.

Add Your Comment

Powered by Sweet Captcha
Verify your real existence,
Drag the speaker to Mr. Director
  • captcha
  • captcha
  • captcha
  • captcha


three - = 1