5

I'm using rsync through Ansible's synchronize-module with the following task definition:

synchronize: src='{{ local_app_path }}/.' dest='{{ remote_app_path }}/' perms=no owner=yes rsync_opts=--delete-after

Running this task generates the following command:

rsync --delay-updates -FF --compress --archive --no-perms --rsh 'ssh  -S none -o StrictHostKeyChecking=no' --rsync-path="sudo rsync" --delete-after --out-format='<<CHANGED>>%i %n%L' "../src/." "vagrant@192.168.55.55:/var/www/app/"

My directory layout goes like this:

src/
    # ...
    app/
    test/
    node_modules/
    package.json
provisioning/
    # ...
    playbook.yml
.rsync-filter

This is my .rsync-filter:

exclude /src/.env
exclude /src/node_modules

Now I am expecting to run my synchronize-task and have the resulting directory-structure on the server look like this (notice the missing node_modules folder):

app/
test/
package.json

This works. However, once I create a node_modules folder on the server...

app/
test/
node_modules/
package.json

...and run the sync again, the node_modules-folder is deleted from the server again (even though I had excluded it in my .rsync-filter):

app/
test/
package.json

I am expecting the node_modules-folder to be kept on the server, because I have it listed in my .rsync-filter and am not using the --delete-excluded option.

How can I prevent my excluded files/directories from being deleted with rsync?

Thanks a lot for your help! :)

Macks
  • 151
  • 1
  • 3

2 Answers2

2

It's the -FF that is causing your problem. That stops the -rsync-filter file being copied across and as the rsync man page says ...

MERGE-FILE FILTER RULES
       ...
       These per-directory rule files must be created on the sending side because it is the
       sending side that is being scanned for the available files to transfer. These rule files may also
       need to be transferred to the receiving side if you want them to affect what files don’t get deleted
       (see PER-DIRECTORY RULES AND DELETE below).

Important bit is the last sentence in that quoted section. Changing -FF to -F gives desired behaviour.

Paul Haldane
  • 4,517
  • 1
  • 21
  • 32
0

I have a very similar issue as the author of OP. So that's what I've found. But, however, I haven't tried it for myself yet. But it should work.

TLDR: I think you need to add "--exclude=node_modules" to your rsync_opts in terms of Ansible.

If you read rsync manual, you will see summary of these options

            --delete                delete extraneous files from dest dirs
            --delete-before         receiver deletes before xfer, not during
            --delete-during         receiver deletes during the transfer
            --delete-delay          find deletions during, delete after
            --delete-after          receiver deletes after transfer, not during
            --delete-excluded       also delete excluded files from dest dirs

The option --delete-excluded is interesting.

--delete-excluded
              In  addition  to deleting the files on the receiving side that
              are not on the sending side, this tells rsync to  also  delete
              any  files  on  the  receiving  side  that  are  excluded (see
              --exclude).  See the FILTER RULES section for a  way  to  make
              individual exclusions behave this way on the receiver, and for
              a way to protect files from --delete-excluded.   See  --delete
              (which is implied) for more details on file-deletion.

but you don't actually need it, sure thing, except for that it references the --exclude option that you need.

--exclude=PATTERN
              This option is a simplified form of the --filter  option  that
              defaults  to  an  exclude  rule  and  does  not allow the full
              rule-parsing syntax of normal filter rules.

              See the FILTER RULES section for detailed information on  this
              option.

Add "--exclude=node_modules" to your rsync_opts.

konstunn
  • 101
  • 1