2

I'm trying to run two simple tasks

Task A starts an Ipref3 server and waits for a client to connect
Task B starts to run from host-1 until the given timeout

once Task B (host-1) is over another Task B run from host-2

Task B starts to run from host-2 until the given timeout

What is a good approach to orchestrating this use-case?

This is what I tried

Task B runs the client from multiple hosts (host-1, host-2, ..)

- name: Run iperf3 client
  win_command: iperf3 -c {{ iperf_server }} -t {{ iperf_time }} 
  args:
    chdir: "{{ iperf_dest }}"
  register: iperf3_out

- debug:
    var: iperf3_out.stdout

Task A run the server

- name: Start iperf3 server
  shell: iperf3 --server
  async: "{{ iperf_async }}" # iperf_async = iperf_time + 10
  poll: "{{ iperf_poll }}"   # iperf_poll  = 0  

Is there a way to know when to confirm Task A is finished before I move to the next task.

NOTE: Order of execution is important Server (Task A) needs to run before the client (Task B)

1

Order of execution is important Server (Task A) needs to run before the client (Task B)

Then why are your running Task A async in that case ? Is it just because iperf --server is not falling in the background and dying as soon as the shell task finishes ? A quick look at the documentation shows we can probably work around that problem with something like:

iperf3 --server --daemon --pidfile /path/to/iperf3.pid --logfile /path/to/log

Notes:

  • I added the logfile option since I guess it can be useful but it is not mandatory for the current issue
  • I took for granted you are running the server on a linux platform. Running it on Windows would apparently slightly change the below scenario. See Running as a service on windows

From what I understand the last unsolved issue is running the client tasks sequentially on each client host. This can be done using the serial keyword on your play.

Here is an untested pseudo ansible setup summarizing what I understand from your requirements. Adapt to your real use-case.

inventory/iperf_hosts.yml

---
iperf_servers:
  vars:
    iperf_pid_file: /tmp/iperf.pid
    iperf_log_file: /tmp/iperf.log
  hosts:
    server1.local:
iperf_clients:
  vars:
    iperf_time: 1
    iperf_dest: some\win\directory
  hosts:
    host1.local:
    host2.local:
    host3.local:

playbook.yml

---
- name: Start the iperf server
  hosts: iperf_servers
  
  tasks:
    - name: Fire the start command
      command: "iperf3 --server --daemon --pidfile {{ iperf_pid_file }} --logfile {{ iperf_log_file }}"

- name: Launch clients one after the other.
  hosts: iperf_clients
  serial: 1
  
  tasks:
    - name: Run iperf3 client
      win_command: "iperf3 -c {{ hostvars[group['iperf_servers'][0]].inventory_hostname }} -t {{ iperf_time }}"
      args:
        chdir: "{{ iperf_dest }}"
      register: iperf3_out

    - debug:
        var: iperf3_out.stdout

- name: Now we are over with clients, kill the server
  hosts: iperf_servers
  # We already gathered facts at first play so we disable here
  # You might want to disable in all other plays if you don't need facts at all
  gather_facts: false

  tasks:
    - name: Slurp pid from file
      slurp:
        path: "{{ iperf_pid_file }}"
      register: slurped_pid

    - name: kill the iperf3 process
      command: "kill {{ slurped_pid.content | b64decode }}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.