Asserting the absence of a previous software version

Hi,

If have the version number of a custom piece of software (configured
by ansible) that is either part of the name of the executable or part
of the it's path, is there any way to tell ansible to perform an
upgrade and remove any previous versions?

So for example, if I have version 114 of my foo app that I install thusly:

/opt/foo-v114/bin/foo

If I want to roll out v115, I guess the idempotentcy will make v115
available, is there any way to assert the absence of any prior version
to v115?

Or is this something that a distro package should handle?

Cheers,

Ben

I don’t have a full solution for your particular problem, but I would definitely look into the “stat” module to determine existence of previous versions, and then register the results of that task into a variable that you can then perform tests upon, and alter playbook behavior accordingly.

Distro packages would be ideal, though, it’s much easier just to rely on their well-tested behavior than to write your own, I would suppose!

-Tim

Hey Tim,

Thanks for the tip. I guess inadvertently you're making the point that
what I'm looking for may be beyond the scope of ansible and might be
better suited to a distro package.

Thanks for the feedback,

Cheers,

Ben

You didn't specify which package manager you were using, but in the case of yum, you can handle this with "--obsoletes". As long as your v115 has the "obsoletes v114" metadata, you can use yum to perform the upgrade.

http://www.centos.org/docs/5/html/5.1/Deployment_Guide/s1-yum-useful-commands.html

"If the |--obsoletes| option is used (i.e. |yum --obsoletes /|<package name/s>|/|, |yum| will process obsolete packages. As such, packages that are obsoleted accross updates will be removed and replaced accordingly. "

So you want something like:

if software is not installed
   install new software
else installed version is older than new version
   remove old software
   install new software
   (perhaps reconfigure and restart services)
fi

As Tim suggests, this is better handled by distribution packaging, but
if you have some custom setup, this may not be possible.

On the surface it looks like something that could be achieved with one
tasks to determine the current state and register the result, follow
by 2 tasks to conditionally add/remove the software.

The tricky bit is determining which package is newer. If your version
numbers are simple integers you may be able to get away with something
like

- name: determine newest installed software version
  shell: find /opt/ -n 'foo-v*' | sed 's/\/opt\/foo-v//' | sort -rn | head -1
  register: installed

- name: remove old software versions
  when: installed.stdout != '' and installed.stdout|int < new_version
  command: to remove old software

- name: install new software version
  when: installed.stdout == '' or installed.stdout|int < new_version
  command: to install new software

where 'new_version' is a variable you have set somewhere.

The above code is untested but might form the basis for something that
works for you.

K

Kahlil (Kal) Hodgson GPG: C9A02289
Head of Technology (m) +61 (0) 4 2573 0382
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415
401 Docklands Drive
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that
the parts you are reassembling were disassembled by you. Therefore,
if you can't get them together again, there must be a reason. By all
means, do not use a hammer." -- IBM maintenance manual, 1925

In this case, I'm not actually using a package manager, since this is
just a custom daemon process we have built. But we're running on arch,
so if we did package this up, we'd be using pacman.

But thanks for the tip about yum --obsoletes, since I'd never heard of
that before.

Hey Kal,

That was pretty much the semantics I was looking for, so I'll give you
suggestion a whirl and weigh it up against the cost of producing a
distro package.

Thanks for your help,

Ben