Skip to content
Snippets Groups Projects
Commit 14e91c04 authored by garciadeblas's avatar garciadeblas Committed by Gerrit Code Review
Browse files

Merge "Add initial support for iperf3, both in client and server modes."

parents 450a7802 f7d9a2b0
No related branches found
No related tags found
No related merge requests found
......@@ -38,6 +38,16 @@ timing:
enqueued: 2016-06-29 14:50:03 +0000 UTC
started: 2016-06-29 14:50:03 +0000 UTC
```
## iperf3
Because iperf3 has a client and server component, the netutils charm can operate
as both. Setting the iperf3 configuration value to True will start iperf3 in
server mode, running as a daemon.
```
$ juju deploy cs:~nfv/netutils client
$ juju deploy cs:~nfv/netutils server iperf3=True
$ juju run-action client/0 iperf host=<ip of server> [...]
```
## Scale out Usage
......
......@@ -44,4 +44,90 @@ dig:
type: string
required:
- host
iperf:
description: ""
params:
host:
description: ""
type: string
port:
description: ""
type: integer
default: 5201
format:
description: ""
type: string
interval:
description: ""
type: string
affinity:
description: ""
type: string
udp:
description: "Use UDP rather than TCP"
type: boolean
default: False
bandwidth:
description: "Set the target bandwidth to n bits/sec (default 1Mbit/sec for UDP, unlimited for TCP)"
type: integer
default: 1
time:
description: "Time, in seconds, to transmit for."
type: integer
default: 10
blockcount:
description: "The number of blocks to transmit"
type: integer
length:
description: "The length of buffer to read or write (default 128KB for TCP, 8KB for UDP)"
type: integer
parallel:
description: "The number of parallel client streams to run"
type: integer
reverse:
description: "Run in reverse mode (server sends, client receives)."
type: boolean
default: false
window:
description: "Window size/socket buffer size."
type: integer
bind:
description: "Bind to a specific interface or multicast address"
type: string
mss:
description: "Set the TCP maximum segment size (MTU - 40 bytes)"
type: integer
no-delay:
description: "Set the TCP no delay, disabling Nagle's algorithm."
type: boolean
default: false
ipv4:
description: "Only use IPv4"
type: boolean
default: false
ipv6:
description: "Only use IPv6"
type: boolean
default: false
tos:
description: "Set the IP 'type of service'"
type: integer
flowlabel:
description: "Set the IPv6 flow label (linux-only)"
type: string
zerocopy:
description: "Use a 'zero copy' method of sending data, such as sendfile(s), instead of the usual write(2)."
type: boolean
default: false
omit:
description: "Omit the first n seconds of the test, to skip past the TCP slow-start period."
type: integer
title:
description: "Prefix every output line with this string."
type: string
congestion:
description: "Set the linux congestion control algorithm."
type: string
required:
- host
#!/usr/bin/env python3
import sys
sys.path.append('lib')
from charms.reactive import main
from charms.reactive import set_state
from charmhelpers.core.hookenv import action_fail
"""
`set_state` only works here because it's flushed to disk inside the `main()`
loop. remove_state will need to be called inside the action method.
"""
set_state('actions.iperf3')
try:
main()
except Exception as e:
action_fail(repr(e))
options:
iperf3:
type: boolean
default: false
description: "Enabling this option will start iperf3 in server mode."
from charmhelpers.core.hookenv import (
status_set,
action_get,
action_set,
action_fail,
action_set,
config,
log,
status_set,
)
from charms.reactive import (
remove_state as remove_flag,
set_state as set_flag,
when,
when_not,
set_state as set_flag,
remove_state as remove_flag,
)
import charms.sshproxy
from subprocess import CalledProcessError
@when_not('netutils.ready')
......@@ -95,3 +98,40 @@ def traceroute():
action_set({'output': result})
finally:
remove_flag('actions.traceroute')
@when('actions.iperf3')
def iperf3():
err = ''
try:
# TODO: read all the flags via action_get and build the
# proper command line to run iperf3
host = action_get('host')
cmd = 'iperf3 -c {} --json'.format(host)
result, err = charms.sshproxy._run(cmd)
except CalledProcessError as e:
action_fail('iperf3 command failed:' + e.output)
else:
action_set({'outout': result})
finally:
remove_flag('actions.iperf3')
@when('config.changed')
def config_changed():
""" Handle configuration changes """
cfg = config()
if cfg.changed('iperf3'):
if cfg['iperf3']:
# start iperf in server + daemon mode
cmd = "iperf3 -s -D"
else:
cmd = "killall iperf3"
try:
charms.sshproxy._run(cmd)
log("iperf3 stopped.")
except CalledProcessError:
log("iperf3 not running.")
else:
log("iperf3 started.")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment