Forum: CFEngine Help
Subject: Merging directory contents - file_select inconsistant with purge?
Author: simonblake
Link to topic: https://cfengine.com/forum/read.php?3,23778,23778#msg-23778

Hi all.

I've a directory on a remote server with files named 

a.*conf
b*.conf
c*.conf

and so forth.  On the client, I have a directory where I want to keep a*.conf 
files in sync with the server, but not touch any other files in the directory.  
If I do:

files:
  "/finaldir"
    handle => "sync_a_files",
    comment => "Sync A files from server",
    file_select  => select_a_files,
    move_obstructions => "true",
    depth_search => recurse("inf"),
    copy_from => sync_cp("$(g.clientfiles)/somedir","$(g.policyhost)");

body file_select select_a_files {
  leaf_name   => { "^a.*conf$" };
  file_result => "leaf_name";
}

Then that keeps the a.*conf files in sync with the server, but it also deletes 
anything in /finaldir that doesn't exist in somedir on the server, with 
slightly surprising  results - if b1234.conf exists on both server and client, 
then it isn't updated, but it isn't deleted, if b1234 exists only on the client 
then it is deleted.  The promise uses the file_select to decide what to copy, 
the purge doesn't seem to heed the file_select and works as if the file_select 
wasn't there.

I guess what I'm after is some kind of "bounded purge" - delete files that 
match a.*conf that don't exist on the server.  I did mess about with this sort 
of idea:

  "/finaldir/a*.conf$"
    handle => "sync_a_files",
    comment => "Sync A files from server",
    file_select  => select_a_files,
    move_obstructions => "true",
    copy_from => sync_cp("$(g.clientfiles)/somedir","$(g.policyhost)");

But all I managed to achieve was randomly creating directories called "a*.conf"

I have thought of some work arounds - I could delete a*.conf on the client 
before running a copy from the server, that would entail copying all the files 
every run, which is ugly.  I have also made it work by sync_cp'ing the server 
dir to a dedicated local directory (say /tmp/afiles), then doing a local file 
comparison:

 "/finaldir/a*.conf$"
    handle => "sync_a_files",
    comment => "Sync A files from local dir",
    file_select  => select_a_files,
    delete => tidy;

body file_select select_a_files {
  exec_program => "/tmp/foo.sh $(this.promiser)";
  file_result => "exec_program";
}

and where /tmp/foo.sh is pretty trivial:

#!/bin/sh

FILE=`basename $1`
TMPDIR="/tmp/afiles"

if [ -e $TMPDIR/$FILE ] ; then
  exit 1
else
  exit 0
fi

This works ok, but a shell call for each file in the directory each run fails 
the elegance test.  So does anybody have a better way of merging directories?

Cheers
Simon

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to