Exemple #1
0
 def create_volume(self,docker_host,voulme_name=None):
     url = self.docker_base_url[docker_host]
     cli = Client(base_url=url)
     if voulme_name:
         cli.create_volume(voulme_name)
     else:
         cli.create_volume()
     return  True
Exemple #2
0
class Docker_interface:
    def __init__(self,
                 net_name='tosker_net',
                 tmp_dir='/tmp',
                 socket='unix://var/run/docker.sock'):
        self._log = Logger.get(__name__)
        self._net_name = net_name
        self._cli = Client(base_url=os.environ.get('DOCKER_HOST') or socket)
        self._tmp_dir = tmp_dir

    # TODO: aggiungere un parametro per eliminare i container se esistono gia'!
    def create(self, con, cmd=None, entrypoint=None, saved_image=False):
        def create_container():
            tmp_dir = path.join(self._tmp_dir, con.name)
            try:
                os.makedirs(tmp_dir)
            except:
                pass
            saved_img_name = '{}/{}'.format(self._net_name, con.name)
            img_name = con.image
            if saved_image and self.inspect(saved_img_name):
                img_name = saved_img_name

            self._log.debug('container: {}'.format(con.get_str_obj()))

            con.id = self._cli.create_container(
                name=con.name,
                image=img_name,
                entrypoint=entrypoint if entrypoint else con.entrypoint,
                command=cmd if cmd else con.cmd,
                environment=con.env,
                detach=True,
                # stdin_open=True,
                ports=[key for key in con.ports.keys()] if con.ports else None,
                volumes=['/tmp/dt'] +
                ([k for k, v in con.volume.items()] if con.volume else []),
                networking_config=self._cli.create_networking_config({
                    self._net_name:
                    self._cli.create_endpoint_config(links=con.link
                                                     # ,aliases=['db']
                                                     )
                }),
                host_config=self._cli.create_host_config(
                    port_bindings=con.ports,
                    # links=con.link,
                    binds=[tmp_dir + ':/tmp/dt'] +
                    ([v + ':' + k
                      for k, v in con.volume.items()] if con.volume else []),
                )).get('Id')

        assert isinstance(con, Container)

        if con.to_build:
            self._log.debug('start building..')
            # utility.print_json(
            self._cli.build(path='/'.join(con.dockerfile.split('/')[0:-1]),
                            dockerfile='./' + con.dockerfile.split('/')[-1],
                            tag=con.image,
                            pull=True,
                            quiet=True)
            # )
            self._log.debug('stop building..')
        elif not saved_image:
            # TODO: da evitare se si deve utilizzare un'immagine custom
            self._log.debug('start pulling.. {}'.format(con.image))
            utility.print_json(self._cli.pull(con.image, stream=True),
                               self._log.debug)
            self._log.debug('end pulling..')

        try:
            create_container()
        except errors.APIError as e:
            self._log.debug(e)
            # self.stop(con)
            self.delete(con)
            create_container()
            # raise e

    def stop(self, container):
        name = self._get_name(container)
        try:
            return self._cli.stop(name)
        except errors.NotFound as e:
            self._log.error(e)

    def start(self, container, wait=False):
        name = self._get_name(container)
        self._cli.start(name)
        if wait:
            self._log.debug('wait container..')
            self._cli.wait(name)
            utility.print_byte(self._cli.logs(name, stream=True),
                               self._log.debug)

    def delete(self, container):
        name = self._get_name(container)
        try:
            self._cli.remove_container(name, v=True)
        except (errors.NotFound, errors.APIError) as e:
            self._log.error(e)
            raise e

    def exec_cmd(self, container, cmd):
        name = self._get_name(container)
        if not self.is_running(name):
            return False
        try:
            exec_id = self._cli.exec_create(name, cmd)
            status = self._cli.exec_start(exec_id)

            # TODO: verificare attendibilita' di questo check!
            check = 'rpc error:' != status[:10].decode("utf-8")
            self._log.debug('check: {}'.format(check))
            return check
        except errors.APIError as e:
            self._log.error(e)
            return False
        except requests.exceptions.ConnectionError as e:
            # TODO: questo errore arriva dopo un timeout di 10 secodi
            self._log.error(e)
            return False

    def create_volume(self, volume):
        assert isinstance(volume, Volume)
        self._log.debug('volume opt: {}'.format(volume.get_all_opt()))
        return self._cli.create_volume(volume.name, volume.driver,
                                       volume.get_all_opt())

    def delete_volume(self, volume):
        name = self._get_name(volume)
        return self._cli.remove_volume(name)

    def get_containers(self, all=False):
        return self._cli.containers(all=all)

    def get_volumes(self):
        volumes = self._cli.volumes()
        return volumes['Volumes'] or []

    def inspect(self, item):
        name = self._get_name(item)
        try:
            return self._cli.inspect_container(name)
        except errors.NotFound:
            pass
        try:
            return self._cli.inspect_image(name)
        except errors.NotFound:
            pass
        try:
            return self._cli.inspect_volume(name)
        except errors.NotFound:
            return None

    def remove_all_containers(self):
        for c in self.get_containers(all=True):
            self.stop(c['Id'])
            self.delete(c['Id'])

    def remove_all_volumes(self):
        for v in self.get_volumes():
            self.delete_volume(v['Name'])

    def create_network(self, name, subnet='172.25.0.0/16'):
        # docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw
        # self.delete_network(name)
        try:
            self._cli.create_network(name=name,
                                     driver='bridge',
                                     ipam={'subnet': subnet},
                                     check_duplicate=True)
        except errors.APIError:
            self._log.debug('network already exists!')

    def delete_network(self, name):
        assert isinstance(name, str)
        try:
            self._cli.remove_network(name)
        except errors.APIError:
            self._log.debug('network not exists!')

    def delete_image(self, name):
        assert isinstance(name, str)
        try:
            self._cli.remove_image(name)
        except errors.NotFound:
            pass

    # TODO: splittare questo metodo in due, semantica non chiara!
    def update_container(self, node, cmd, saved_image=True):
        assert isinstance(node, Container)
        # self._log.debug('container_conf: {}'.format(node.host_container))
        stat = self.inspect(node.image)
        old_cmd = stat['Config']['Cmd'] or None
        old_entry = stat['Config']['Entrypoint'] or None

        if self.inspect(node):
            self.stop(node)
            self.delete(node)
        self.create(node, cmd=cmd, entrypoint='', saved_image=saved_image)

        self.start(node.id, wait=True)
        self.stop(node.id)

        name = '{}/{}'.format(self._net_name, node.name)

        self._cli.commit(node.id, name)

        self.stop(node)
        self.delete(node)
        self.create(node,
                    cmd=node.cmd or old_cmd,
                    entrypoint=node.entrypoint or old_entry,
                    saved_image=True)

        self._cli.commit(node.id, name)

    def is_running(self, container):
        name = self._get_name(container)
        stat = self.inspect(name)
        stat = stat is not None and stat['State']['Running'] is True
        self._log.debug('State: {}'.format(stat))
        return stat

    def _get_name(self, name):
        if isinstance(name, six.string_types):
            return name
        else:
            assert isinstance(name, (Container, Volume))
            return name.name
Exemple #3
0
 def create(cls, url, version, name, driver='local'):
     cli = Client(base_url=url, version=version)
     cli.create_volume(name=name, driver=driver)
Exemple #4
0
async def up(loop):
    name = 'test1'
    output_port = 5000
    cli = Client()
    volumes = cli.volumes()['Volumes']
    if volumes:
        volume = next((v for v in volumes if v['Name'] == name), None)
        if volume:
            print('deleting existing volume')
            cli.remove_volume(name)
    volume = cli.create_volume(name=name)
    vol_mount_point = volume['Mountpoint']

    github_oauth = os.getenv('GITHUB_OAUTH')
    assert github_oauth, 'GITHUB_OAUTH env variable not set'

    ctrl_port = output_port + 1
    con_name = '{}_ctrl'.format(name)
    ctrl_con = cli.create_container(
        image='hackle-box:latest',
        name=con_name,
        environment={
            'GITHUB_USER': '******',
            'GITHUB_REPO': 'tutorcruncher.com',
            'GITHUB_OAUTH': github_oauth,
        },
        volumes=['/src'],
        host_config=cli.create_host_config(
            port_bindings={8000: ctrl_port},
            binds=['{}:/src'.format(vol_mount_point)],
        ))
    cli.start(container=ctrl_con.get('Id'))

    url = 'http://localhost:{}'.format(ctrl_port)
    print('waiting for control server to start...')
    async with aiohttp.ClientSession(loop=loop) as session:
        for i in range(20):
            try:
                async with session.get(url) as r:
                    status = r.status
            except (aiohttp.ClientOSError, aiohttp.ClientResponseError) as e:
                await asyncio.sleep(1)
                continue
            print('ctrl server "{}" running at {}, status {}'.format(
                con_name, url, status))
            break

    dev_port = output_port
    con_name = '{}_dev'.format(name)
    await asyncio.sleep(
        1
    )  # make sure volumes have synced, otherwise jekyll can get ito a mess
    dev_con = cli.create_container(
        image='jekyll/jekyll',
        name=con_name,
        volumes=['/srv/jekyll'],
        working_dir='/srv/jekyll',
        command='/usr/bin/jekyll serve -H 0.0.0.0 --incremental',
        host_config=cli.create_host_config(
            port_bindings={4000: dev_port},
            binds=['{}:/srv/jekyll'.format(vol_mount_point)],
        ))
    cli.start(container=dev_con.get('Id'))
    print('dev server "{}" running at http://localhost:{}'.format(
        con_name, dev_port))
Exemple #5
0
 def create(cls, url, version, name, driver='local'):
     cli = Client(base_url=url, version=version)
     cli.create_volume(name=name, driver=driver)
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)