0

It's unfortunate that there is no current API that would allow us to work with docker volumes. At the moment if I need to copy data into a docker volume (NB: not a docker container) I must first ensure that some container can access the volume, and then use ansible to run docker cp. But for these kind of tasks, there may not even be docker containers which have the volume mounted. This is not idempotent. This disallows the vast majority of ansible's generally awesome API. This complicates the process by adding many extra steps. This is not the ansible way. What if we could simply find the mountpoints for each volume we are interested in, and then have ansible talk to the host's filesystem directly?

So let's say we have some list of the names of some docker volumes we'll be using. For each item in the list, we'd like to inspect it using the docker daemon, then use ansible to set a fact about its mountpoint. This is what I have so far:

- name: Get docker volume information
  command: "docker volume inspect {{ item }}"
  register: output
  with_items: "{{ volumes }}"

NB: Command returns something like this:

 [
    {
        "Name": "docker_sites-enabled",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/docker_sites-enabled/_data",
        "Labels": null,
        "Scope": "local"
    }
]

Playbook continues:

- name: Set volume facts
  set_fact:
    "{{ item.stdout|from_json|json_query('Name') }}": "{{ item.stdout|from_json|json_query('Mountpoint') }}"
  with_items: "{{ output.results }}"

- name: The following facts are now set
  debug:
    var: "{{ item }}"
  with_items:
    - "{{ volumes }}"

However, this doesn't work as I expected it to as ansible reports error "The variable name '' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores. It's probably because of the syntax of the JSON query filter I'm using, but I can't find any documentation about how I should be using it.

DMCoding
  • 1,167
  • 2
  • 15
  • 30
  • Instead of "*something like this*" can you show **exactly** what is in the `output` variable? You know how to use `debug` module... – techraf Feb 07 '17 at 03:35
  • Also what's the value of `volumes`? And which task fails? You included `The following facts are now set` -- shall I assume it's the one giving the error? If the previous one fails, what was the purpose of including the last one in the question? – techraf Feb 07 '17 at 03:41

1 Answers1

1

Not sure why do you want to generate root-level variables for each volume.

You can do like this:

- hosts: docker_host
  become: true
  gather_facts: false
  vars:
    volumes:
      - vol1
      - vol2
      - vol4
  tasks:
    - shell: docker volume inspect {{ volumes | join(' ') }}
      register: vlm_res

    - set_fact: mountpoints={{ dict(vlm_res.stdout | from_json | json_query('[].[Name,Mountpoint]')) }}

    - debug: var=mountpoints['vol2']

mountpoints is a dict, so we can access mountpoints['vol2'] to access vol2's mountpoint.

Konstantin Suvorov
  • 65,183
  • 9
  • 162
  • 193
  • Yep, there's not strictly-speaking a need for the variables to be root-level. Thanks for the reply! – DMCoding Feb 07 '17 at 10:56