move_obstructions behavior

10 views
Skip to first unread message

Ron Peters

unread,
Jul 12, 2023, 5:36:16 PM7/12/23
to help-cfengine
Hi all,

I'm creating a link and have move_obstructions set to false. If a file/directory already exists, I do NOT want to move it. Functionally, it works perfectly but from the move_obstructions docs: " if a file is blocking the creation of a directory, then normally CFEngine will report an error.".

In my case, it's not an error, it's working as expected. I wonder if this shouldn't be reported as an error but simply a notification or nothing if I specifically set : move_obstructions => "false";

I watch for errors and this ends up being a false positive. I was thinking of reporting a bug/feature request but thought I'd try here first if there's a way to avoid the error(s).

Thanks.

Nick Anderson

unread,
Jul 12, 2023, 6:27:29 PM7/12/23
to ron.b....@gmail.com, help-cfengine

Hi Ron,

It's very helpful if you provide a small standalone policy that demonstrates the behavior. I think this does it:

bundle agent __main__
{
  files:
    "/tmp/move-obstructions.txt"
      content => "I am a plain file";

    "/tmp/move-obstructions.txt"
      move_obstructions => "false",
      link_from => default:ln_s( "$(this.promise_filename)" );
}
 info: Created file '/tmp/move-obstructions.txt', mode 0600
 info: Updated file '/tmp/move-obstructions.txt' with content 'I am a plain file'
error: Object '/tmp/move-obstructions.txt' is obstructing promise
error: Unable to create link '/tmp/move-obstructions.txt' -> '/home/nickanderson/org/roam/daily/work/cfengine3-0cVlsi', failed to move obstruction
error: Errors encountered when actuating files promise '/tmp/move-obstructions.txt'

Based on your description alone, I can see the sense in not emitting an error when move_obstructions is false. Indeed, if you are explicit about not wanting to move something out of the way it seems a bit silly to emit an error. However it also seems like this might be better expressed in the policy to simply avoid making a promise in that case.

This policy will create the link because there is no file there.

bundle agent __main__
{
  files:

    "/tmp/move-obstructions.txt"
      delete => default:tidy;

    "/tmp/move-obstructions.txt"
      link_from => default:ln_s( "$(this.promise_filename)" ),
      if => not( fileexists( "/tmp/move-obstructions.txt" ) ),
      comment =>  "If there is nothing there, we want to have a symlink";

}
info: Deleted file '/tmp/move-obstructions.txt'
info: Linked files '/tmp/move-obstructions.txt' -> '/home/nickanderson/org/roam/daily/work/cfengine3-gp5E8s'

But what if there is a symlink, but it's pointing elsewhere? With move_obstructions => "false" (the default) the symlink target won't be fixed:

bundle agent __main__
{
  files:

      "/tmp/move-obstructions.txt"
        delete => default:tidy;

      "/tmp/move-obstructions.txt"
        link_from => default:ln_s( "/etc/hosts" ),
        if => not( fileexists( "/tmp/move-obstructions.txt" ) ),
        comment =>  "If there is nothing there, we link the file to /etc/hosts";

      "/tmp/move-obstructions.txt"
        link_from => default:ln_s( "/etc/issue" ),
        if => islink( "/tmp/move-obstructions.txt" ),
        comment =>  "If it's a symlink, we fix the link";

      "/tmp/move-obstructions.txt"
        link_from => default:ln_s( "/etc/motd" ),
        if => islink( "/tmp/move-obstructions.txt" ),
        move_obstructions => "true",
        comment =>  "If it's a symlink, we fix the link";

}
 info: Deleted file '/tmp/move-obstructions.txt'
 info: Linked files '/tmp/move-obstructions.txt' -> '/etc/hosts'
error: Link '/tmp/move-obstructions.txt' points to '/etc/hosts' not '/etc/issue', but not moving obstructions
error: Errors encountered when actuating files promise '/tmp/move-obstructions.txt'
 info: Overrode incorrect link '/tmp/move-obstructions.txt'
 info: Linked files '/tmp/move-obstructions.txt' -> '/etc/motd'

So, what do you think? Do you still think that explicitly setting move_obstructions => "false" should suppress the error about not moving things out of the way?

Actually, looking at this and reviewing the docs, I think the link should have been updated since that was already the same type of file. Still, I think it's a bit better to be more explicit about the conditions under which you want to actually make the promise. Based on your description not wanting to replace a file or directory with a link, but presumably wanting to fix a link that is pointing to the wrong place I would probably write it like this:

bundle agent __main__
{
  files:
    "/tmp/move-obstructions.txt"
      content => "I am a plain file";

    "/tmp/move-obstructions.txt"
      move_obstructions => "true",
      link_from => default:ln_s( "/etc/motd" ),
      if => islink( "$(this.promiser)" ),
      comment => concat( "If the file is a symlink, be sure to make sure it",
                         " points to the correct place, if the file is a plain",
                         " file or directory or socket etc ... then just leave it alone." );
}

Ron Peters

unread,
Jul 13, 2023, 11:55:54 AM7/13/23
to help-cfengine
Hi Nick,

Yes, that's very helpful. I briefly scanned this yesterday and felt silly for asking when I realized I could simply qualify when the link was created. Thanks for a very useful and detailed writeup.

Nick Anderson

unread,
Jul 13, 2023, 12:57:46 PM7/13/23
to Ron Peters, help-c...@googlegroups.com

Ron Peters <ron.b....@gmail.com> writes:

Hi Nick,

Yes, that's very helpful. I briefly scanned this yesterday and felt silly for asking when I realized I could simply qualify when the link was created. Thanks for a very useful and detailed writeup.

Great, glad you found it useful!

Reply all
Reply to author
Forward
0 new messages