예제 #1
0
def connect_container_to_network(container, net_id, links):
    try:
        docker_cli = Client(base_url=docker_socket)
        docker_cli.connect_container_to_network(container, net_id, links=links)
    except Exception, e:
        log.exception('failed-connection-to-network',
                      container=container,
                      net_id=net_id,
                      e=e)
        raise
예제 #2
0
class SwarmConnector(object):
    def __init__(self, url):
        self.url = url
        self.consul_url = "consul://vm-imdmresearch-keller-06.eaalab.hpi.uni-potsdam.de:8500"

        self.nodes = []
        self.instances = []

        self.workload_is_set = False
        self.throughput = 0

        self.docker = Client(base_url='tcp://vm-imdmresearch-keller-01.eaalab.hpi.uni-potsdam.de:8888', timeout=180) #TODO
        self.lock = threading.Lock()

        self.dispatcher_url = "" #internal ip
        self.master_url = ""
        self.dispatcher_node_url = ""
        self.dispatcher_ip = "" # external ip to receive queries


    def set_url(self, url):
        self.url = url

    def connect(self):
        self.docker = Client(base_url=self.url, timeout=180)
        self.connected = True
        return self.docker.info()

    def update_nodes_and_instances(self):

        ## Nodes
        self.lock.acquire()
        try:
            # We need to use a local client here as this command cannot be executed within swarm
            local_docker = Client(base_url='tcp://vm-imdmresearch-keller-01.eaalab.hpi.uni-potsdam.de:2375') # TODO: remove remote IP
            container = local_docker.create_container(image='swarm', command='list {}'.format(self.consul_url))
            start = local_docker.start(container=container.get('Id'))
            wait = local_docker.wait(container=container.get('Id'))
            output = local_docker.logs(container=container.get('Id'))
            local_docker.remove_container(container=container.get('Id'), force=True)

            # swarm list prints an info line before the actual nodes
            response = [n for n in output.decode("utf-8").split('\n') if "level" not in n]

            print(response)

            if response:
                self.nodes = [{"hostname": n.split('.')[0].replace('keller-', ''), "runningContainers": 0} for n in response if n != ''] # TODO: find a more reliable way to return the hostname

            if self.dispatcher_node_url != "":
                r = requests.get("http://" + self.dispatcher_node_url + ":8080/node_info")
                instances_info = r.json()['hosts']
            else:
                instances_info = None
            print(instances_info)

            ## Instances

            if not self.docker:
                return "Error: not connected to swarm"

            containers = self.docker.containers(all=True, filters={'status': 'running'})
            instances = []
            for container in containers:
                info = self.docker.inspect_container(container=container.get('Id'))

                if "hyrise/dispatcher" in container["Image"]:
                    instances.append({
                        "type": "Dispatcher",
                        "name": container["Names"][0],
                        "node": container["Names"][0].split('/')[1].replace('keller-', ''),
                        "Id": container["Id"],
                        "ip": info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]
                    })
                    self.dispatcher_url = info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]
                    self.dispatcher_node_url = info["Node"]["Addr"].split(':')[0]
                    self.dispatcher_ip = info["Node"]["IP"]

                elif "hyrise/hyrise_nvm" in container["Image"]:
                    swarm_ip = info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]
                    queries = 0
                    total_time = 0
                    throughput = "n.a."
                    if instances_info:
                        info = [i for i in instances_info if i['ip'] == swarm_ip]
                        if len(info) == 1:
                            queries = int(info[0]['total_queries'])
                            total_time = int(info[0]['total_time'])
                            if queries != 0:
                                throughput = "%.2f ms" % (total_time/queries/1000)

                    instances.append({
                        "type": container["Labels"]["type"].capitalize(),
                        "name": container["Names"][0],
                        "node": container["Names"][0].split('/')[1].replace('keller-', ''),
                        "Id": container["Id"],
                        "ip": swarm_ip,
                        "throughput": throughput,
                        "totalTime": total_time,
                        "queries": queries
                    })
            self.instances = instances
            for node in self.nodes:
                node["runningContainers"] = sum(1 for i in instances if i["node"] == node["hostname"])


            for instance in self.instances:
                container_exec = self.docker.exec_create(
                    container=instance["Id"],
                    cmd="cat /proc/loadavg",
                )

                load = self.docker.exec_start(
                    exec_id=container_exec["Id"]
                )

                instance["load"] = load.decode(encoding='UTF-8').split(' ')[0] # TODO: do the split with awk in exec cmd
        except Exception:
            print("Exception")
        self.lock.release()


    def get_nodes(self):
        return self.nodes

    def get_instances(self):
        return self.instances

    def reset_instances(self):
        if not self.docker:
            return "Error: not connected to swarm"

        self.lock.acquire()
        containers = self.docker.containers(all=True)
        for container in containers:
            if "hyrise" in container["Image"]:
                self.docker.remove_container(container=container.get('Id'), force=True)
        self.instances = []
        for node in self.nodes:
            node["runningContainers"] = 0

        self.dispatcher_url = ""
        self.master_url = ""
        self.dispatcher_node_url = ""
        self.dispatcher_ip = ""
        self.lock.release()


    def start_dispatcher(self):
        container = self.docker.create_container(
            image='hyrise/dispatcher:docker',
            command='./start_dispatcher 8080 settings.json',
            ports=[8080],
            labels={"type": "dispatcher"},
            host_config=self.docker.create_host_config(port_bindings={
                8080: 8080, # expose dispatcher for debugging. TODO: remove
            })
        )
        start = self.docker.start(container=container.get('Id'))
        connect = self.docker.connect_container_to_network(container=container.get('Id'), net_id="swarm_network")
        info = self.docker.inspect_container(container=container.get('Id'))

        self.dispatcher_url = info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]

        # for accessing the dispatcher from outside the swarm cluster
        self.dispatcher_node_url = info["Node"]["Addr"].split(':')[0]

        return {"node": info["Node"]["Addr"], "ip": info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]}

    def start_master(self):
        container = self.docker.create_container(
            image='hyrise/hyrise_nvm:latest',
            command='/bin/bash -c "sleep 2 && wget http://vm-imdmresearch-keller-01.eaalab.hpi.uni-potsdam.de:8000/ORDER_LINE.tbl && \
                     ./build/hyrise-server_release --dispatcherurl="{}" --dispatcherport="8080" --port=5001 --corecount=2 --nodeId=0"'.format(self.dispatcher_url),
            ports=[5001],
            labels={"type": "master"}
        )
        start = self.docker.start(container=container.get('Id'))
        connect = self.docker.connect_container_to_network(container=container.get('Id'), net_id="swarm_network")
        info = self.docker.inspect_container(container=container.get('Id'))

        self.master_url = info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]
        return {"node": info["Node"]["Addr"], "ip": info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]}


    def start_replica(self):
        container = self.docker.create_container(
            image='hyrise/hyrise_nvm:latest',
            command='/bin/bash -c "sleep 2 && wget http://vm-imdmresearch-keller-01.eaalab.hpi.uni-potsdam.de:8000/ORDER_LINE.tbl && \
                     ./build/hyrise-server_release --masterurl="{}" --dispatcherurl="{}" --dispatcherport="8080" --port=5001 --corecount=2 --nodeId={}"'.format(self.master_url, self.dispatcher_url, len(self.instances)),
            ports=[5001],
            labels={"type": "replica"}
        )
        start = self.docker.start(container=container.get('Id'))
        connect = self.docker.connect_container_to_network(container=container.get('Id'), net_id="swarm_network")
        info = self.docker.inspect_container(container=container.get('Id'))

        return {"node": info["Node"]["Addr"], "ip": info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]}

    def remove_replica(self):
        if not self.docker:
            return "Error: not connected to swarm"

        self.lock.acquire()
        containers = self.docker.containers(all=True)
        for container in containers:
            if "hyrise/hyrise_nvm" in container["Image"]:
                info = self.docker.inspect_container(container=container.get('Id'))
                ip = info["NetworkSettings"]["Networks"]["swarm_network"]["IPAddress"]
                if ip != self.master_url:
                    print('remove_node')
                    try:
                        requests.get("http://" + self.dispatcher_node_url + ":8080/remove_node/%s:" % ip, timeout=1)
                    except Exception:
                        print('remove')
                        self.docker.remove_container(container=container.get('Id'), force=True)
                        print('removed')
                        break
        self.lock.release()
        return


    def get_throughput(self):
        return {"system": [time.time(), self.throughput]}


    def set_workload(self, status):
        print("set workload", status)
        if int(status) == 1:
            self.workload_is_set = True
        else:
            self.workload_is_set = False
        return
예제 #3
0
class DockerOrchestration(object):
    """
    Class to perform operations on docker for various data source manipulations, updating configurations and handle users.
    """
    def __init__(self, headers, docker_host, docker_port, payload=None):
        """
        Initialize the grafana connection object necessary to perform any configuration or object manipulation
        :param api_key:
        :param headers:
        :param docker_host:
        :param docker_port:
        :return:
        """
        if not docker_host:
            raise ValueError(
                "Docker hostname value is %s missing. Instance cannot be initialized"
                % docker_host)

        if not docker_port:
            raise ValueError(
                "Docker hostport value is %s missing. Instance cannot be initialized"
                % docker_port)

        if not headers:
            raise ValueError(
                "Docker connection header value is missing. Instance cannot be initialized"
            )

        if not isinstance(docker_host, str):
            raise ValueError("Docker hostname must be of string type")

        if not isinstance(headers, dict):
            raise ValueError("Docker deader  must be of dict type")

        self.headers = headers
        self.docker_host = docker_host
        self.docker_port = docker_port
        self.payload = payload
        self.docker_client = Client(base_url='unix:///var/run/docker.sock')
        self.client = docker.from_env(assert_hostname=False)

    def create_docker_container(self, command=None):
        """
        To create the new container on the VM
        :return:
        """
        container = self.docker_client.create_container(
            image='busybox:latest', command='/bin/sleep 30')
        print("Container created : %s" % container)

    def update_docker_container(self):
        """
        To update the existing docker container
        :return:
        """
        update_container = self.docker_client.update_container()
        print(update_container)

    def create_docker_volume(self, command=None):
        """
        Create and register a named volume
        :param command:
        :return:
        """
        volume = self.docker_client.create_volume(name='foobar',
                                                  driver='local',
                                                  driver_opts={
                                                      'foo': 'bar',
                                                      'baz': 'false'
                                                  })
        print(volume)

    def create_docker_network(self, name_of_network, driver, options=None):
        """
        To create a network
        :param name_of_network:
        :param driver:
        :param options:
        :return:
        """
        network = self.docker_client.create_network(name='foobar',
                                                    driver='local',
                                                    driver_opts={
                                                        'foo': 'bar',
                                                        'baz': 'false'
                                                    })
        print(network)

    def connect_container_to_network(self,
                                     container_id_or_name=None,
                                     network_id=None):
        """
        TO connect a container to network
        :return:
        """
        network = self.docker_client.connect_container_to_network(
            '%s', '%s') % (container_id_or_name, network_id)
        print(network)

    def disconnect_container_to_network(self,
                                        container_id_or_name=None,
                                        network_id=None):
        """
        TO connect a container to network
        :return:
        """
        network = self.docker_client.disconnect_container_from_network(
            '%s', '%s') % (container_id_or_name, network_id)
        print(network)

    def docker_version(self):
        """
        To return the version of current running docker on the server.
        :return:
        """
        version = self.docker_client.version()
        return version

    def get_docker_volumes(self):
        """
        To get the volumes of currently registered by the docker daemon
        :return:
        """
        volumes = self.docker_client.volumes()
        print(volumes)

    def get_docker_version(self, client):
        """
        To get the docker version
        :return:
        """
        version_number = self.client.version()
        print(version_number)

    def create_container_with_mount_docker_tempfs(self,
                                                  name=None,
                                                  cmd=None,
                                                  payload=None):
        """
        To create a container with the specified paths to be mounted with tmpfs.
        :param name:
        :param cmd:
        :param payload:
        :return:
        """
        create_container = self.docker_client.create_container()
        pass

    def build_docker(
        self,
        dockerfile=None,
    ):
        """
        To build the docker from the docker file.
        :return:
        """
        f = BytesIO(dockerfile.encode('utf-8'))
        response = [
            line for line in self.docker_client.build(
                fileobj=f, rm=True, tag='yourname/volume')
        ]
        print(response)

    def get_docker_images(self):
        """
        TO list the docker images
        :return:
        """
        image_list = self.docker_client.images()
        print(image_list)

    def get_docker_image(self, docker_image_name=None):
        """
        To get an image from docker daemon.
        :return:
        """
        image = self.docker_client.get_image("fedora:latest")
        image_tar = open('/tmp/fedora - latest.tar', 'w')
        image_tar.write(image.data)
        image_tar.close()

    def import_docker_image(self):
        """
        To import docker image.
        :return:
        """
        image_list = self.docker_client.import_image()
        print(image_list)

    def import_docker_image_from_data(self):
        """
        To import image from data
        :return:
        """
        image_list = self.docker_client.import_image_from_data()
        print(image_list)

    def import_docker_image_from_image(self):
        """
        To import image from data
        :return:
        """
        image_list = self.docker_client.import_image_from_image()
        print(image_list)

    def import_docker_image_from_stream(self):
        """
        To import image from data
        :return:
        """
        image_list = self.docker_client.import_image_from_stream()
        print(image_list)

    def import_docker_image_from_url(self):
        """
        To import image from data
        :return:
        """
        image_list = self.docker_client.import_image_from_url()
        print(image_list)

    def get_docker_networks(self):
        """
        Get the list of network for the dockers
        :return:
        """
        network_list = self.docker_client.networks()
        print(network_list)

    def push_docker_image_to_repository(
        self,
        dockerfile=None,
    ):
        """
        To build the docker from the docker file.
        :return:
        """
        f = BytesIO(dockerfile.encode('utf-8'))
        response = [
            line for line in self.docker_client.build(
                fileobj=f, rm=True, tag='yourname/volume')
        ]
        print(response)

    def pull_docker_image_to_repository(
        self,
        dockerfile=None,
    ):
        """
        To pull the docker image from repository
        :param dockerfile:
        :return:
        """

        for line in self.docker_client.pull('busybox', stream=True):
            print(json.dumps(json.loads(line), indent=4))

    def search_docker_image(self, docker_image_name=None):
        """
        To search and return docker image
        :param docker_image_name:
        :return:
        """
        response = self.docker_client.search('%s') % docker_image_name
        print(response[:2])

    def start_docker_container(self,
                               docker_image_name=None,
                               docker_command=None):
        """
        To start the docker after it has created.
        :param docker_image_name:
        :param docker_command:
        :return:
        """
        container = self.docker_client.create_container(
            image='busybox:latest', command='/bin/sleep 30')
        response = self.docker_client.start(container=container.get('Id'))
        print(response)

    def restart_docker_container(self, container_dict=None, time_out=None):
        """
        To re-start the docker after it has created.
        :param docker_image_name:
        :param docker_command:
        :return:
        """
        response = self.docker_client.restart(container_dict, time_out)
        print(response)

    def check_status_for_docker_container(self, container_name=None):
        """
        To generate the statistics for the specific container.
        :param docker_image_name:
        :param docker_command:
        :return:
        """
        stats_obj = self.docker_client.stats('elasticsearch')
        #self.docker_client.stop('elasticsearch')
        for stat in stats_obj:
            print(stat)

    def remove_docker_image(
        self,
        dockerfile=None,
    ):
        """
        To remove docker image
        :param dockerfile:
        :return:
        """
        response = [
            line
            for line in self.docker_client.push('yourname/app', stream=True)
        ]
        print(response)