conditional gziping of files

Hi All,

I'm using the following task to ensure static files have an up to date pre-compressed version (so nginx can serve them more quickly):

- name: 'ensure static files have been gziped'
   with_lines:
     - find $src_path/root/static/ -regex '.*\.\(css\|js\)$' || true
   shell: gzip -n -9 -c $item > $item.gz;

This takes _ages_ to complete (like whole seconds). Ideally I'd only like to run the command if the modification time of $item is more recent than $item.gz. (Like a Makefile would).

I've tried something like

- name: 'ensure static files have been gziped'
   with_lines:
     - find $src_path/root/static/ -regex '.*\.\(css\|js\)$' || true
   shell: >
  if [ $item -nt $item.gz ];
  then
      gzip -n -9 -c $item > $item.gz;
  else
      true;
  fi

(needs to return true so the task doesn't fail)

This appears to work, but looks absolutely awful.

Any ideas on a better approach?

Cheers,

Kal

A few things here. For every 'with_lines' you're making a new ssh
connection to the box to gzip one item. You'd be much better off dropping
the 'with_lines' and just putting the whole thing in one shell call.
Something like this: (untested psuedo-bash-code)

- name: 'ensure static files have been gziped'
  shell: find $src_path/root/static/ -regex '.*\.\(css\|js\)$' -print0 |
xargs -0 -n 10 `if [ -- -nt "--".gz ] then gzip -n -9 -c "--".gz else true
fi`

That way it's run in one ssh connection. There are probably cleaner/better
shell ways to do it but you get the idea :slight_smile: (try to fit it in one ssh
invocation). Another easy way I'd be tempted to deal with this is just
create a nice little script for this and use ansible's 'script' module to
push it down and run it or better yet create yourself a ansible module to
do it! :slight_smile:

Hello Romeo,

A few things here. For every 'with_lines' you're making a new ssh
connection to the box to gzip one item. You'd be much better off
dropping the 'with_lines' and just putting the whole thing in one shell
call.

Curiously, I'm actually running this as a 'local_action' ... my thinking is definitely not right.

Another easy way I'd be tempted to deal with
this is just create a nice little script for this and use ansible's
'script' module to push it down and run it or better yet create yourself
a ansible module to do it! :slight_smile:

I think I may be trying to use the wrong 'hammer' to hit this one. A module may be the right way to go. Basically I want to run some local pre-processing before I run a play. I could just wrap this in a little script, but where would it live? This pre-processing is intrinsically linked with the task, never used anywhere else. I don't to have to maintain a little independent pre-proc script that gets shared with the admins.

Wondering if a there is scope for a 'prep' module that does some pre-task local pre-processing, that is, runs a local script under, say,'./bin', and can be nicely bundled with the playbook.

Cheers,

Kal

This may actually be a great case for the 'script' module, which is a
way of pushing and running an arbitrary script.

Excellent idea! Works brilliantly. I've added a corresponding pro-tip:

     https://coderwall.com/p/xlbxkq

Thanks guys!

K