Working with async jobs that require an extra call to an api to check their state

23 views
Skip to first unread message

Nestor Manrique

unread,
Nov 16, 2016, 12:06:49 PM11/16/16
to Ansible Project
Hello,

I've been diving into ansible most recently because I wan't to automate the management of several virtual environments deployed with OVM (oracle virtualization solution for x86 using xen). I found an ansible module created for oracle cloud that implements most of the functionalities to manage a VM (take a peek at the oracle_ovm file) but I'm writing my own to also provide check mode and have a better feedback of the status of the running jobs, set some timeouts for them and autoabort options too. OVM Manager (the console to manage the VMs, it's like a Vcenter) exposes an API. The ansible module I just referenced takes a naive approach about the api jobs just waiting for them to finish (forever) and if they do finish, it assumes they were succesful.

The problem I have is I don't know how to get feedback about the jobs while they are running. I already read the doc about async jobs, and it seemed the "fire and forget + check later" approach would help but there's one problem. The api works this way: if I request to do a post/put request like "Stop VM" (i.e "post api/rest/vm/stop") it returns a jobId. This ID can be used to check the status of the async job using another api call (i.e "get api/rest/job/<id>"). So, what I tried to do was pass the jobId to the "check later" task and call the same module requesting another state that is supposed to return the job status at a given time until it's finished. That didn't worked =(, the playbook complains because I'm not able to call modules if async_status is present (I believe this might be the problem I'm not completely sure, again, I'm just noobing here).

I will paste some lines now, I hope my explanation is good enough, let me know if you need any more insight.

#### ovm module ####
    .
    .
    .
    # Send job to stop the vm and return the id of it in the job variable
    elif module.params["state"] == "stop":
        job = stopVm(restSession,module)
        module.exit_json(msg='vm stopped', changed=True, job=job['id']['value'])
    .
    .
    .
    # Get the job info and return it in the job variable
    elif module.params["state"] == "jobinfo":
        jobinfo = getJobInfo(restSession,module.params["jobId"],module)
        module.exit_json(msg=jobinfo, changed=False, job=jobinfo)

#### playbook ####
- hosts: 127.0.0.1
  connection: local

  tasks:

    - name: 'Stop Vm test'
      oracle_ovm2:
        state: stop
        user: xxxxxx
        password: xxxxxx
        vmName: test
        ovmHostname: ovmm-test
        ovmPort: 7002
      async: 3000
      poll: 0
      register: stop_job

    - name: 'OVM Check stop job'
      oracle_ovm2:
        state: jobinfo
        user: xxxxxxxxxx
        password: xxxxx
        vmName: test
        ovmHostname: ovmm-test
        ovmPort: 7002
        jobId: "{{ stop_job.job }}"
      async_status: jid={{ stop_job.ansible_job }}
      register: job_result
      until: job_result.job['summaryDone']
      retries: 10
      delay: 30
      failed_when: job_result.job['jobRunState'] != 'SUCCESS'

If you run the playbook like that it complains about parse errors. Those errors go away if I take away the module call in the second task but then how can I send the get request to the api for the jobinfo?

Thank you very much in advance,

Nestor
Reply all
Reply to author
Forward
0 new messages