<commit_before>#
#  Copyright (C) 2014 Dell, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from .errors import BlockadeError, InsufficientPermissionsError
from .utils import docker_run

import collections
import itertools
import re

BLOCKADE_CHAIN_PREFIX = "blockade-"
IPTABLES_DOCKER_IMAGE = "vimagick/iptables:latest"


class NetworkState(object):
    NORMAL = "NORMAL"
    SLOW = "SLOW"
    FLAKY = "FLAKY"
    DUPLICATE = "DUPLICATE"
    UNKNOWN = "UNKNOWN"


class BlockadeNetwork(object):
    def __init__(self, config):
        self.config = config

    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 duplicate(self, device):
        duplicate_config = self.config.network['duplicate'].split()
        traffic_control_netem(device, ["duplicate"] + duplicate_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 get_container_device(self, docker_client, container_id):
        exec_handle = docker_client.exec_create(container_id, ['ip', 'link', 'show', 'eth0'])
        res = docker_client.exec_start(exec_handle).decode('utf-8')
        device = re.search('^([0-9]+):', res)
        if not device:
            raise BlockadeError(
                "Problem determining host network device for container '%s'" %
                (container_id))

        peer_idx = int(device.group(1))

        # all my experiments showed the host device index was
        # one greater than its associated container device index
        host_idx = peer_idx + 1
        host_res = docker_run(
            'ip link',
            image=IPTABLES_DOCKER_IMAGE,
            docker_client=docker_client
        )

        host_rgx = '^%d: ([^:@]+)[:@]' % host_idx
        host_match = re.search(host_rgx, host_res, re.M)
        if not host_match:
            raise BlockadeError(
                "Problem determining host network device for container '%s'" %
                (container_id))

        host_device = host_match.group(1)

        return host_device


def parse_partition_index(blockade_id, chain):
    prefix = "%s%s-p" % (BLOCKADE_CHAIN_PREFIX, blockade_id)
    if chain and chain.startswith(prefix):
        try:
            return int(chain[len(prefix):])
        except ValueError:
            pass
    raise ValueError("chain %s is not a blockade partition" % (chain,))


def partition_chain_name(blockade_id, partition_index):
    return "%s%s-p%s" % (BLOCKADE_CHAIN_PREFIX, blockade_id, partition_index)


def iptables_call_output(*args):<commit_msg>Refactored to not require containers to have `ip`<commit_after>#
#  Copyright (C) 2014 Dell, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from .errors import BlockadeError
from .utils import docker_run

import collections
import itertools
import re

BLOCKADE_CHAIN_PREFIX = "blockade-"
IPTABLES_DOCKER_IMAGE = "vimagick/iptables:latest"


class NetworkState(object):
    NORMAL = "NORMAL"
    SLOW = "SLOW"
    FLAKY = "FLAKY"
    DUPLICATE = "DUPLICATE"
    UNKNOWN = "UNKNOWN"


class BlockadeNetwork(object):
    def __init__(self, config):
        self.config = config

    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 duplicate(self, device):
        duplicate_config = self.config.network['duplicate'].split()
        traffic_control_netem(device, ["duplicate"] + duplicate_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 get_container_device(self, docker_client, container_id):
        exec_handle = docker_client.exec_create(container_id, ['cat', '/sys/class/net/eth0/ifindex'])
        res = docker_client.exec_start(exec_handle).decode('utf-8')
        device = res.strip()
        if not device:
            raise BlockadeError(
                "Problem determining host network device for container '%s': got %s" %
                (container_id, res))

        # all my experiments showed the host device index was
        # one greater than its associated container device index
        host_idx = int(device) + 1
        host_res = docker_run(
            'ip link',
            image=IPTABLES_DOCKER_IMAGE,
            docker_client=docker_client
        )

        host_rgx = '^%d: ([^:@]+)[:@]' % host_idx
        host_match = re.search(host_rgx, host_res, re.M)
        if not host_match:
            raise BlockadeError(
                "Problem determining host network device for container '%s': ip link shows: \n%s" %
                (container_id, host_res))

        host_device = host_match.group(1)

        return host_device


def parse_partition_index(blockade_id, chain):
    prefix = "%s%s-p" % (BLOCKADE_CHAIN_PREFIX, blockade_id)
    if chain and chain.startswith(prefix):
        try:
            return int(chain[len(prefix):])
        except ValueError:
            pass
    raise ValueError("chain %s is not a blockade partition" % (chain,))


def partition_chain_name(blockade_id, partition_index):
    return "%s%s-p%s" % (BLOCKADE_CHAIN_PREFIX, blockade_id, partition_index)


def iptables_call_output(*args):
{'fraction_non_alphanumeric': 0.0971709717097171, 'fraction_numerical': 0.0036900369003690036, 'mean_word_length': 3.1817142857142855, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4495667', 'n_tokens_mistral': 2233, 'n_tokens_neox': 2140, 'n_words': 586}