# Idempotent unpacking

**URL:** <https://forum.ansible.com/t/idempotent-unpacking/11953>\
**Category:** Ansible Project\
**Tags:** ansible-project\
**Created:** [October 4, 2012, 12:04pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953 "2012-10-04T12:04:05Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [October 4, 2012, 12:04pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/1 "2012-10-04T12:04:05Z")

</div>

Try this. Though you'll want 0.8 such that the boolean works as you  
would expect.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- action: get\_url ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register: get\_url\_result

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- action: command tar ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;only\_if: "${get\_url\_result.changed}"

(Adding an easier alternative to the only\_if syntax is on the top of  
my list for 0.9)

---

<div class="post-metadata">

**Author:** ![Chamberlain\_Darren](https://avatars.discourse-cdn.com/v4/letter/c/ee7513/32.png) [@Chamberlain\_Darren](https://forum.ansible.com/u/Chamberlain_Darren)\
**Post date:** [October 4, 2012, 2:00pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/2 "2012-10-04T14:00:14Z")

</div>

Seems like this request could be grouped with the easy conditionals  
stuff earmarked for 0.9; there could be when\_file\_exists and  
when\_file\_not\_exists conditions (or possibly better names like  
creates) which would translate to:

&nbsp;&nbsp;&nbsp;only\_if: "True == os.path.isfile('/path/to/created/file')"

In related news, Ben, you can use the above only\_if now.

\* Michael DeHaan \<michael.dehaan at gmail.com\> [2012/10/04 08:04]:

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [October 4, 2012, 2:08pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/3 "2012-10-04T14:08:41Z")

</div>

Not really. The easy conditional stuff is probably going to compile  
down to an only\_if, and not result in network tests.

It will get as easy as this though:

when: changed('variable\_name')

and maybe even automagic registering of previous commands via a stack, like

when: changed('previous')

or maybe even

when: changed('task\_name')

---

<div class="post-metadata">

**Author:** ![Ben\_Hood](https://avatars.discourse-cdn.com/v4/letter/b/8c91f0/32.png) [@Ben\_Hood](https://forum.ansible.com/u/Ben_Hood)\
**Post date:** [November 22, 2012, 10:08pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/4 "2012-11-22T22:08:53Z")

</div>

Michael,

> Try this. Though you’ll want 0.8 such that the boolean works as you  
> would expect.
> 
> - action: get\_url …  
> register: get\_url\_result
> 
> - action: command tar …  
> only\_if: “${get\_url\_result.changed}”
> 
> (Adding an easier alternative to the only\_if syntax is on the top of  
> my list for 0.9)

Thanks for the heads up on this (and sorry about the very late reply to your post).

I don’t suppose that this construct would work with my current factoring:

- name: Fetch Remote Packages  
action: get\_url url=$s3/$item dest=/opt/$item  
with\_items:
- $tarball1
- $tarball2
- $tarball3  
tags:
- download

Would I need to break this up to register the boolean, or could I put it into the loop somehow?

Cheers,

Ben

---

<div class="post-metadata">

**Author:** ![Daniel\_Hokka\_Zakriss](https://avatars.discourse-cdn.com/v4/letter/d/f05b48/32.png) [@Daniel\_Hokka\_Zakriss](https://forum.ansible.com/u/Daniel_Hokka_Zakriss)\
**Post date:** [November 22, 2012, 10:25pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/5 "2012-11-22T22:25:02Z")

</div>

Ben Hood wrote:

> Michael,
> 
> > Try this. Though you'll want 0.8 such that the boolean works as you  
> > would expect.
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- action: get\_url ...  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register: get\_url\_result
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- action: command tar ...  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;only\_if: "${get\_url\_result.changed}"
> > 
> > (Adding an easier alternative to the only\_if syntax is on the top of  
> > my list for 0.9)
> 
> Thanks for the heads up on this (and sorry about the very late reply to  
> your post).
> 
> I don't suppose that this construct would work with my current factoring:
> 
> - name: Fetch Remote Packages  
> &nbsp;&nbsp;action: get\_url url=$s3/$item dest=/opt/$item  
> &nbsp;&nbsp;with\_items:  
> &nbsp;&nbsp;&nbsp;&nbsp;- $tarball1  
> &nbsp;&nbsp;&nbsp;&nbsp;- $tarball2  
> &nbsp;&nbsp;&nbsp;&nbsp;- $tarball3  
> &nbsp;&nbsp;tags:  
> &nbsp;&nbsp;&nbsp;&nbsp;- download
> 
> Would I need to break this up to register the boolean, or could I put it  
> into the loop somehow?

Are you wanting to extract each tarball depending on whether or not that  
particular one has changed, or do you want to run it if any of them change?

The former would likely be best implemented using a task include file  
containing your get\_url and unpacking command, and using with\_items on the  
include, e.g.  
&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;- include: fetch-extract.yml url=$s3/$item name=$item  
&nbsp;&nbsp;&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;- $tarball1  
&nbsp;&nbsp;&nbsp;&nbsp;- $tarball2  
and in fetch-extract.yml:  
&nbsp;&nbsp;- name: fetch file  
&nbsp;&nbsp;&nbsp;&nbsp;action: get\_url url=$url dest=/opt/$name  
&nbsp;&nbsp;&nbsp;&nbsp;register: fetch\_result  
&nbsp;&nbsp;- name: extract file  
&nbsp;&nbsp;&nbsp;&nbsp;action: command tar -xzf /opt/$name  
&nbsp;&nbsp;&nbsp;&nbsp;when\_boolean: ${fetch\_result.changed}

The latter would be easier, just add register: foo and use ${foo.changed}.  
It will be True if any of the items was changed, and False if they were all  
unchanged.

Daniel

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [November 22, 2012, 10:49pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/6 "2012-11-22T22:49:24Z")

</div>

I do not see a register in your example but generally except for yum and apt combining with items and register would only store the last result

– Michael

---

<div class="post-metadata">

**Author:** ![Daniel\_Hokka\_Zakriss](https://avatars.discourse-cdn.com/v4/letter/d/f05b48/32.png) [@Daniel\_Hokka\_Zakriss](https://forum.ansible.com/u/Daniel_Hokka_Zakriss)\
**Post date:** [November 22, 2012, 10:57pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/7 "2012-11-22T22:57:43Z")

</div>

Michael DeHaan wrote:

> I do not see a register in your example but generally except for yum and  
> apt combining with items and register would only store the last result

No, register: on a with\_items gets a dict with changed being the sum of all  
changed, and results being a list of the results for each item.

Daniel

---

<div class="post-metadata">

**Author:** ![Ben\_Hood](https://avatars.discourse-cdn.com/v4/letter/b/8c91f0/32.png) [@Ben\_Hood](https://forum.ansible.com/u/Ben_Hood)\
**Post date:** [November 22, 2012, 11:26pm UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/8 "2012-11-22T23:26:18Z")

</div>

> Are you wanting to extract each tarball depending on whether or not that  
> particular one has changed, or do you want to run it if any of them change?

The former.

> The former would likely be best implemented using a task include file  
> containing your get\_url and unpacking command, and using with\_items on the  
> include, e.g.  
> tasks:  
> - include: fetch-extract.yml url=$s3/$item name=$item  
> &nbsp;&nbsp;&nbsp;with\_items:  
> &nbsp;&nbsp;&nbsp;- $tarball1  
> &nbsp;&nbsp;&nbsp;- $tarball2  
> and in fetch-extract.yml:  
> - name: fetch file  
> &nbsp;&nbsp;&nbsp;action: get\_url url=$url dest=/opt/$name  
> &nbsp;&nbsp;&nbsp;register: fetch\_result  
> - name: extract file  
> &nbsp;&nbsp;&nbsp;action: command tar -xzf /opt/$name  
> &nbsp;&nbsp;&nbsp;when\_boolean: ${fetch\_result.changed}

OK, I'll give that a go - thanks for the heads up.

BTW how does the register action populate the ${fetch\_result.changed} flag? Does the get\_url command save a checksum of the last downloaded file?

Cheers,

Ben

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [November 23, 2012, 1:33am UTC](https://forum.ansible.com/t/idempotent-unpacking/11953/9 "2012-11-23T01:33:16Z")

</div>

I can't remember how all the stuff I wrote works 🙂

Good.

-- Michael
