'join' a list and a dict

175 views
Skip to first unread message

Mikael Sandström

unread,
Sep 26, 2014, 9:00:59 AM9/26/14
to ansible...@googlegroups.com
Hi,

I've got the following structures (or at least I'm hoping to be able to use them)

list_of_files:
       
- { filename: file1, version: 1 }
       
- { filename: file2, version: 1 }
       
- { filename: file3, version: 1 }
       
- { filename: file1, version: 2 }
       
- { filename: file2, version: 2 }
       
- { filename: file1, version: 3 }
       
- { filename: file1, version: 4 }
       
- { filename: file1, version: 5 }
       
- { filename: file2, version: 5 }

dict_name
:                                    
        key1
:                                
             type
: x        
             dictversion
: 1          
        key2
:                                
             type
: y        
             dictversion
: 2
        key3
:                                
             type
: z        
             dictversion
: 1        

 

I'd like to use dict_name.key.dictversion to download all files from list_of_files where dict_name.keyX.dictversion==list_of_files.version. 
Meaning, for each key, I'd like to get the (variable) number of files with the versionnumber that specific key has.


I tried with this:

  - name: Get files
    get_url
: url={{ source }}/{{ item.0.filename }} dest={{ somewhere }}
    with_together
:
       
- dict_name
       
- list_of_files
   
when: "{{ dict_name[item.1].dictversion }}" == "{{ item.0.version }}

But it doesnt work. It errors out with a stacktrace:
  File "/usr/lib/python2.7/site-packages/ansible/runner/__init__.py", line 561, in _executor
    exec_rc = self._executor_internal(host, new_stdin)
  File "/usr/lib/python2.7/site-packages/ansible/runner/__init__.py", line 696, in _executor_internal
    complex_args=complex_args
  File "/usr/lib/python2.7/site-packages/ansible/runner/__init__.py", line 756, in _executor_internal_inner
    if not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars):
  File "/usr/lib/python2.7/site-packages/ansible/utils/__init__.py", line 254, in check_conditional
    conditional = template.template(basedir, conditional, inject, fail_on_undefined=fail_on_undefined)
  File "/usr/lib/python2.7/site-packages/ansible/utils/template.py", line 115, in template
    varname = template_from_string(basedir, varname, vars, fail_on_undefined)
  File "/usr/lib/python2.7/site-packages/ansible/utils/template.py", line 357, in template_from_string
    res = jinja2.utils.concat(rf)
  File "<template>", line 10, in root
  File "/usr/lib/python2.7/site-packages/jinja2/environment.py", line 372, in getattr
    return getattr(obj, attribute)
  File "/usr/lib/python2.7/site-packages/jinja2/runtime.py", line 463, in __getattr__
    return self._fail_with_undefined_error()
  File "/usr/lib/python2.7/site-packages/jinja2/runtime.py", line 457, in _fail_with_undefined_error
    raise self._undefined_exception(hint)
UndefinedError: dict object has no element None


Is this even possible? 

I could work around this by adding something like a 'download: true/false' to the list and use that in the when:, but I really like the to be able to control which files to get by using the dictversion variable in dict_name

regards
/Micke



Serge van Ginderachter

unread,
Sep 26, 2014, 10:10:44 AM9/26/14
to ansible...@googlegroups.com

​Try targetting the values of the dict:​


with_together:
       
- dict_name
​.values()​

       
- list_of_files


Mikael Sandström

unread,
Sep 27, 2014, 6:27:18 AM9/27/14
to ansible...@googlegroups.com
Ok, haven't seen that before and I'm starting to think I'm getting out of my depth here, so efter a lot of trial I managed this:

---
- hosts: localhost
  connection
: local
  gather_facts
: false
   vars
:
     ble
: true
     list_of_files
:
       
- { filename: file1-v1, version: 1 }
       
- { filename: file2-v1, version: 1 }
       
- { filename: file3-v1, version: 1 }
       
- { filename: file1-v2, version: 2 }
       
- { filename: file2-v2, version: 2 }
       
- { filename: file1-v3, version: 3 }
       
- { filename: file1-v4, version: 4 }
       
- { filename: file1-v5, version: 5 }
       
- { filename: file2-v5, version: 5 }


     dict_name
:                                    
        key1
:                                
             type
: x        
             dictversion
: 1          
        key2
:                                
             type
: y        
             dictversion
: 2
        key3
:                                
             type
: z        
             dictversion
: 1


  tasks
:
 
- name: Get files
    debug
: msg="filename is; {{ item.1.filename }}, dict-key is; {{ item.0 }}, dict-version is; {{ item.0.dictversion }}"
    with_together
:
       
- dict_name.values()
       
- list_of_files
   
when: ble and  "{{ item.0.dictversion }}" == "{{ item.1.version }}"

which gave me this:

PLAY [localhost] **************************************************************


TASK
: [Get files] *************************************************************
ok
: [localhost] => (item=[{'type': 'z', 'dictversion': 1}, {'version': 1, 'filename': 'file1-v1'}]) => {
   
"item": [
       
{
           
"dictversion": 1,
           
"type": "z"
       
},
       
{
           
"filename": "file1-v1",
           
"version": 1
       
}
   
],
   
"msg": "filename is; file1-v1, dict-key is; {'type': 'z', 'dictversion': 1}, dict-version is; 1"
}
skipping
: [localhost] => (item=[{'type': 'y', 'dictversion': 2}, {'version': 1, 'filename': 'file2-v1'}])
ok
: [localhost] => (item=[{'type': 'x', 'dictversion': 1}, {'version': 1, 'filename': 'file3-v1'}]) => {
   
"item": [
       
{
           
"dictversion": 1,
           
"type": "x"
       
},
       
{
           
"filename": "file3-v1",
           
"version": 1
       
}
   
],
   
"msg": "filename is; file3-v1, dict-key is; {'type': 'x', 'dictversion': 1}, dict-version is; 1"
}
fatal
: [localhost] => Traceback (most recent call last):

 
File "/usr/lib/python2.7/site-packages/ansible/runner/__init__.py", line 561, in _executor
    exec_rc
= self._executor_internal(host, new_stdin)
 
File "/usr/lib/python2.7/site-packages/ansible/runner/__init__.py", line 696, in _executor_internal
    complex_args
=complex_args
 
File "/usr/lib/python2.7/site-packages/ansible/runner/__init__.py", line 756, in _executor_internal_inner
   
if not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars):
 
File "/usr/lib/python2.7/site-packages/ansible/utils/__init__.py", line 254, in check_conditional
    conditional
= template.template(basedir, conditional, inject, fail_on_undefined=fail_on_undefined)
 
File "/usr/lib/python2.7/site-packages/ansible/utils/template.py", line 115, in template
    varname
= template_from_string(basedir, varname, vars, fail_on_undefined)
 
File "/usr/lib/python2.7/site-packages/ansible/utils/template.py", line 357, in template_from_string
    res
= jinja2.utils.concat(rf)
 
File "<template>", line 10, in
root
 
File "/usr/lib/python2.7/site-packages/jinja2/runtime.py", line 485, in _fail_with_undefined_error
   
raise self._undefined_exception(hint)
UndefinedError: 'None' has no attribute 'dictversion'


FATAL
: all hosts have already failed -- aborting

So something is obviously wrong. 

Any ideas?

regards
/Micke

Mikael Sandström

unread,
Oct 1, 2014, 1:32:46 PM10/1/14
to ansible...@googlegroups.com
So I havent made any progress with this, and given the lack of response I take it this will not work?

The workaround hack it is then

/Micke

Michael DeHaan

unread,
Oct 2, 2014, 4:46:43 PM10/2/14
to ansible...@googlegroups.com
Probably that nobody is trying it :)



--
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.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/b50b8424-9bd5-4bca-b1ee-725ca2520533%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Mikael Sandström

unread,
Oct 7, 2014, 2:59:53 AM10/7/14
to ansible...@googlegroups.com
Yeah, fair enough ;)

It would be interesting to know though if this isn't working because:

1. It should/could work but I'm not doing it right
2. It doesnt/will not work and I should just stop trying

Either way, the stacktrace is kinda ugly?
Reply all
Reply to author
Forward
0 new messages