Problem with: yum module, with_items, composite-variable

1,312 views
Skip to first unread message

Asad Khan

unread,
Mar 1, 2013, 1:48:41 PM3/1/13
to ansible...@googlegroups.com
Variable resolution seems to fail on the second iteration of a with_items used with yum, but only if the variable is "composite" i.e. an expression involving other variables.

Here is the playbook:

vars:
    pkg_list:
      - jdk
      - httpd

    pkg_versions: { "jdk": "1.6.0_31-fcs", "httpd": "2.2.15-15.el6.centos.1" }

  tasks:

    - name: Composite-Variable resolution works fine with the copy module
      action: copy src=/tmp/${item}-${pkg_versions.${item}} dest=/tmp
      with_items: ${pkg_list}

    - name: .. but does not work with the yum module
      action: yum pkg=${item}-${pkg_version.${item}} state=installed          ## This doesn't work
      #action: yum pkg=${item} state=installed          ## This works
      with_items: ${pkg_list}

The output is:

[ansible@dev-autoserver-01 ~]$ ansible-playbook /etc/ansible/sys-plays/testyumbug.yml -v

PLAY [Test Playbook] ********************* 

GATHERING FACTS ********************* 
ok: [10.120.210.61]

TASK: [Composite-Variable resolution works fine with the copy module] ********************* 
ok: [10.120.210.61] => (item=jdk) => {"changed": false, "dest": "/tmp/jdk-1.6.0_31-fcs", "group": "root", "item": "jdk", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "src": "/home/ansible/.ansible/tmp/ansible-1362162055.67-15730396780203/jdk-1.6.0_31-fcs", "state": "file"}
ok: [10.120.210.61] => (item=httpd) => {"changed": false, "dest": "/tmp/httpd-2.2.15-15.el6.centos.1", "group": "root", "item": "httpd", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "src": "/home/ansible/.ansible/tmp/ansible-1362162056.13-226327540995443/httpd-2.2.15-15.el6.centos.1", "state": "file"}

TASK: [.. but does not work with the yum module] ********************* 
failed: [10.120.210.61] => (item=jdk,httpd) => {"changed": true, "failed": true, "item": "jdk,httpd", "rc": 0, "results": ["\n================================================================================\n Package       Arch             Version                     Repository     Size\n================================================================================\nInstalling:\n jdk           x86_64           2000:1.6.0_38-fcs           srt            56 M\n\nTransaction Summary\n================================================================================\nInstall       1 Package(s)\n\nTotal download size: 56 M\nInstalled size: 121 M\nUnpacking JAR files...\n\trt.jar...\n\tjsse.jar...\n\tcharsets.jar...\n\ttools.jar...\n\tlocaledata.jar...\n\tplugin.jar...\n\tjavaws.jar...\n\tdeploy.jar...\n\nInstalled:\n  jdk.x86_64 2000:1.6.0_38-fcs                                                  \n\n"]}
msg: No Package matching 'httpd-${pkg_version.${item}}' found available, installed or updated

FATAL: all hosts have already failed -- aborting


I don't have a workaround yet, other than to either try to debug the yum module, or code my own replacement module.
(The above is a completely contrived example just to reproduce the issue - the actual use-case is more involved and involves proprietary rpm's; it's not feasible to unroll the loop - I need to work with a list )

Michael DeHaan

unread,
Mar 1, 2013, 2:02:24 PM3/1/13
to ansible...@googlegroups.com
It just looks like something is missing in your hash to me. Here's a
much much cleaner way to do that:

vars:
packages:
- { name: 'foo', version: 'xyz' }
- { name: 'bar', version: 'xyz' }

tasks:
- yum: name=${item.name}-${item.version} state=installed
with_items: $packages

In general, when you start to use variables in ways where they all
nest like that, it's time to simplify things. Ansible playbooks
should be very easy to read.
> --
> You received this message because you are subscribed to the Google Groups
> "Ansible Project" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ansible-proje...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Asad Khan

unread,
Mar 1, 2013, 3:18:13 PM3/1/13
to ansible...@googlegroups.com
I'm on 1.0, and I experimented with your suggestion:

  vars:
     pkgs:
       - { name: "jdk", version: "1.6.0_31-fcs" }
       - { name: "httpd", version: "2.2.15-15.el6.centos.1" }

  tasks:
     - name: New style variable resolution
       action: copy src=/tmp/${item.name}-${item.version} dest=/tmp
       with_items: $pkgs

    - name: .. but does not work with the yum module
      action: yum name=${item.name}-${item.version} state=installed
      with_items: $pkgs

I got the following:

LAY [Test Playbook] ********************* 

GATHERING FACTS ********************* 
ok: [10.120.210.61]

TASK: [New style variable resolution] ********************* 
ok: [10.120.210.61] => (item={'version': '1.6.0_31-fcs', 'name': 'jdk'}) => {"changed": false, "dest": "/tmp/jdk-1.6.0_31-fcs", "group": "root", "item": {"name": "jdk", "version": "1.6.0_31-fcs"}, "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "src": "/home/ansible/.ansible/tmp/ansible-1362168335.16-67188730965918/jdk-1.6.0_31-fcs", "state": "file"}
ok: [10.120.210.61] => (item={'version': '2.2.15-15.el6.centos.1', 'name': 'httpd'}) => {"changed": false, "dest": "/tmp/httpd-2.2.15-15.el6.centos.1", "group": "root", "item": {"name": "httpd", "version": "2.2.15-15.el6.centos.1"}, "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "src": "/home/ansible/.ansible/tmp/ansible-1362168335.63-42039443662886/httpd-2.2.15-15.el6.centos.1", "state": "file"}

TASK: [.. but does not work with the yum module] ********************* 
fatal: [10.120.210.61] => Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/ansible/runner/__init__.py", line 237, in _executor
    exec_rc = self._executor_internal(host)
  File "/usr/lib/python2.6/site-packages/ansible/runner/__init__.py", line 287, in _executor_internal
    inject['item'] = ",".join(items)
TypeError: sequence item 0: expected string, dict found


FATAL: all hosts have already failed -- aborting


Could this be a 1.0 vs 1.1 issue?

Michael DeHaan

unread,
Mar 1, 2013, 3:37:28 PM3/1/13
to ansible...@googlegroups.com
There is no 1.1 issue, I just gave you a bad example syntax.

name="foo=1.0"

Not a dash.

Daniel Hokka Zakrisson

unread,
Mar 1, 2013, 4:29:51 PM3/1/13
to ansible...@googlegroups.com
This is from the yum/apt optimization for with_items. Can you file an issue
on Github for it?

Daniel

> FATAL: all hosts have already failed -- aborting
>
>
> Could this be a 1.0 vs 1.1 issue?
>
>
>
>
>
>
> On Friday, March 1, 2013 2:02:24 PM UTC-5, Michael DeHaan wrote:
>>
>> It just looks like something is missing in your hash to me. Here's a
>> much much cleaner way to do that:
>>
>> vars:
>> packages:
>> - { name: 'foo', version: 'xyz' }
>> - { name: 'bar', version: 'xyz' }
>>
>> tasks:
>> - yum: name=${item.name}-${item.version} state=installed
>> with_items: $packages
>>
>> In general, when you start to use variables in ways where they all
>> nest like that, it's time to simplify things. Ansible playbooks
>> should be very easy to read.
>>
>>
>> On Fri, Mar 1, 2013 at 1:48 PM, Asad Khan
>> <asad....@gmail.com<javascript:>>
>> > email to ansible-proje...@googlegroups.com <javascript:>.

Michael DeHaan

unread,
Mar 1, 2013, 4:33:31 PM3/1/13
to ansible...@googlegroups.com
>
> This is from the yum/apt optimization for with_items. Can you file an issue
> on Github for it?

While this is the root cause, it doesn't detract from that being
something we can simplify and not even get into that corner :)

Asad Khan

unread,
Mar 1, 2013, 4:38:24 PM3/1/13
to ansible...@googlegroups.com, dan...@hozac.com
OK, doing so

Asad Khan

unread,
Mar 1, 2013, 4:53:15 PM3/1/13
to ansible...@googlegroups.com, dan...@hozac.com

Michael DeHaan

unread,
Mar 1, 2013, 6:33:57 PM3/1/13
to ansible...@googlegroups.com
Fixed! Yeah the with_items optimization shouldn't run in this case.
And now it doesn't, you should be good to go!

On Fri, Mar 1, 2013 at 4:53 PM, Asad Khan <asad....@gmail.com> wrote:
> Ticket here:
>
> https://github.com/ansible/ansible/issues/2258

Asad Khan

unread,
Mar 1, 2013, 9:11:00 PM3/1/13
to ansible...@googlegroups.com
Nice. I will test this out soon, thank you!

Dmitry Horbach

unread,
Jun 7, 2013, 8:45:59 AM6/7/13
to ansible...@googlegroups.com
Hi,

I have a slightly different case - I'm trying to composite package name with full path to RPM

- name: installing required packages
  action: yum name=$tmp_dir/$item state=installed
  with_items: 
    - packageA.rpm
    - packageB.rpm   
  sudo: yes
  
  Name will be resolved as /tmp/packageA.rpm,packageB.rpm which correctly resolves only for the first package.

Is there any better way to install multiple rpm's using absolute path?

Michael DeHaan

unread,
Jun 7, 2013, 11:23:08 AM6/7/13
to ansible...@googlegroups.com
The yum module automatically combines with_items to avoid multiple transactions, so no, that won't work.

Since you are installing local RPMs, switch to the command or shell module and call RPM, perhaps.

--Michael



--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

seth vidal

unread,
Jun 7, 2013, 5:22:18 PM6/7/13
to ansible...@googlegroups.com, dim.h...@gmail.com
On Fri, 7 Jun 2013 05:45:59 -0700 (PDT)
Dmitry Horbach <dim.h...@gmail.com> wrote:

> Hi,
>
> I have a slightly different case - I'm trying to composite package
> name with full path to RPM
>
> - name: installing required packages
> > action: yum name=$tmp_dir/$item state=installed
> > with_items:
> > - packageA.rpm
> > - packageB.rpm
> > sudo: yes
>
>
> Name will be resolved as* */tmp/packageA.rpm,packageB.rpm which
> correctly resolves only for the first package.
>
> Is there any better way to install multiple rpm's using absolute path?
>


OR do this:
- name: installing required packages
action: yum name=$item state=installed
with_items:
- $tmp_dir/packageA.rpm
- $tmp_dir/packageB.rpm
sudo: yes

-sv

Dmitry Horbach

unread,
Jun 11, 2013, 8:12:26 AM6/11/13
to ansible...@googlegroups.com, dim.h...@gmail.com
Thanks for suggestions.
Initially i was using with_items:  - $tmp_dir/packageA.rpm but this gives a lot of duplicated prefixes.
Also as I try to move all configuration items into vars files I ended up with nice sets which can be overriden on role level.


  vars:
set_version: 8
rpmset_8:
- packageA.rpm
- packageB.rpm
rpmset: $rpmset_{{ set_version }}
 
task:  

- name: installing rpms
command: /bin/rpm -Uhv $tmp_dir/{{ item }}
with_items: $rpmset
Drawback - multiple transactions. Can yum module support something optional like chdir parameter?

Michael DeHaan

unread,
Jun 12, 2013, 6:44:31 AM6/12/13
to ansible...@googlegroups.com, dim.h...@gmail.com
No chdir parameter.

I would go with Seth's suggestion above as it solves the with_items question, and also does one transaction.


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply all
Reply to author
Forward
0 new messages