Notebook
class NetworkState(object): NORMAL = "NORMAL" SLOW = "SLOW" FLAKY = "FLAKY" UNKNOWN = "UNKNOWN" class BlockadeNetwork(object): def __init__(self, config): self.config = config def new_veth_device_name(self): chars = string.ascii_letters + string.digits return "veth" + "".join(random.choice(chars) for _ in range(8)) def network_state(self, device): return network_state(device) def flaky(self, device): flaky_config = self.config.network['flaky'].split() traffic_control_netem(device, ["loss"] + flaky_config) def slow(self, device): slow_config = self.config.network['slow'].split() traffic_control_netem(device, ["delay"] + slow_config) def fast(self, device): traffic_control_restore(device) def restore(self, blockade_id): clear_iptables(blockade_id) def partition_containers(self, blockade_id, partitions): clear_iptables(blockade_id) partition_containers(blockade_id, partitions) def get_ip_partitions(self, blockade_id): return iptables_get_source_chains(blockade_id) def traffic_control_restore(device): cmd = ["tc", "qdisc", "del", "dev", device, "root"] p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) _, stderr = p.communicate() stderr = stderr.decode() if p.returncode != 0: if p.returncode == 2 and stderr: if "No such file or directory" in stderr: return # TODO log error somewhere? raise BlockadeError("Problem calling traffic control: " + " ".join(cmd)) def traffic_control_netem(device, params): try: cmd = ["tc", "qdisc", "replace", "dev", device, "root", "netem"] + params subprocess.check_call(cmd) except subprocess.CalledProcessError: # TODO log error somewhere? raise BlockadeError("Problem calling traffic control: " + " ".join(cmd)) def network_state(device): try: output = subprocess.check_output( ["tc", "qdisc", "show", "dev", device]).decode() # sloppy but good enough for now if " delay " in output: return NetworkState.SLOW if " loss " in output: return NetworkState.FLAKY return NetworkState.NORMAL except subprocess.CalledProcessError: # TODO log error somewhere? return NetworkState.UNKNOWN