Example #1
0
def check():
    """
        Check plans and Docker environment
    """

    # plans
    loader = Loader()
    console.info(f'loaded [bold]{len(loader.valid_plans())}[/] valid plans')

    # docker
    try:
        client = docker.from_env()
        info = client.info()
        console.info(f'docker server version: [bold]{info.get("ServerVersion")}[/]')

        # network container
        client.images.get(config.net_container_name())
        console.info(f'network image [bold]\'{config.net_container_name()}\'[/] exists')

        # dwn docker  network
        client.networks.get(config.net_name())
        console.info(f'docker network [bold]\'{config.net_name()}\'[/] exists')

    except ImageNotFound as _:
        console.warn(f'network image [bold]\'{config.net_container_name()}\'[/] does not exist. '
                     f'build it with the [bold]\'network build-container\'[/] command')

    except NotFound as _:
        console.warn(f'docker network [bold]\'{config.net_name()}\'[/] not found.'
                     f'use  [bold]\'docker network create {config.net_name()}\'[/] to should solve that.')

    except DockerException as e:
        console.error(f'docker client error type [dim]{type(e)}[/]: [bold]{e}[/]')

    console.info('[green]everything seems to be ok to use dwn![/]')
Example #2
0
    def stop_net(self, outside: int, inside: int):
        """
            Stops a specific network container
        """

        for container in self.containers():
            if container.name == self.get_net_container_name_with_ports(
                    outside, inside):
                console.info(
                    f'stopping network container for [green]{inside}[/]<-[red]{outside}[/]'
                )
                container.stop()
Example #3
0
def stop(name, yes):
    """
        Stop a plan
    """

    if not yes:
        if not click.confirm(f'are you sure you want to stop containers for plan {name}?'):
            console.info('not stopping any plans')
            return

    loader = Loader()
    if not (plan := loader.get_plan(name)):
        console.error(f'unable to find plan [bold]{name}[/]')
        return
Example #4
0
    def _ensure_net_exists(self):
        """
            Ensures that the network image and docker network exists.
        """

        try:
            self.get_client().images.get(config.net_container_name())
            self.get_client().networks.get(config.net_name())
        except ImageNotFound as _:
            console.info(
                f'network image [bold]{config.net_container_name()}[/] does not exist, quickly building it'
            )
            _, logs = self.get_client().images.build(
                path=str(NETWORK_CONTAINER_PATH),
                pull=True,
                tag=config.net_container_name(),
                rm=True,
                forcerm=True)

            for log in logs:
                console.debug(log)

            console.info(
                f'network container [bold]{config.net_container_name()}[/] built'
            )
            self._ensure_net_exists()

        except NotFound as _:
            console.info(
                f'docker network [bold]{config.net_name()}[/] does not exist, creating it'
            )
            self.get_client().networks.create(name=config.net_name(),
                                              check_duplicate=True)
            self._ensure_net_exists()
Example #5
0
def pull(name):
    """
        Pull plan images.
    """

    plan_targets = []

    if not name and not click.confirm('> a plan name was not specified, '
                                      'pull all valid plan images?'):
        return

    try:
        client = docker.from_env()
    except DockerException as e:
        console.error(f'failed to connect to docker: [bold]{e}[/e]')
        return

    loader = Loader()

    if name:
        plan_targets.append(loader.get_plan(name))
    else:
        [plan_targets.append(n) for n in loader.valid_plans()]

    for p in plan_targets:
        try:
            console.info(f'pulling image [bold]{p.image}:{p.version}[/]')
            client.images.pull(p.image, tag=p.version)
        except ImageNotFound as e:
            console.error(f'failed to pull image: [bold]{e}[/]')
            continue
        except DockerException as e:
            console.error(f'a docker exception occurred: [bold]{e}[/]')
            continue

        console.info(
            f'image [bold]{p.image}:{p.version}[/] for plan [cyan]{p.name}[/] pulled'
        )
Example #6
0
def build_container():
    """
        Builds the network container
    """

    console.info('building network container')

    try:
        client = docker.from_env()
    except DockerException as e:
        console.error(f'docker client failed: [bold]{e}[/]')
        return

    console.debug(f'path to docker context is: [bold]{NETWORK_CONTAINER_PATH}[/]')
    console.debug(f'network container will be called [bold]\'{config.net_container_name()}\'[/]')

    image, logs = client.images.build(
        path=str(NETWORK_CONTAINER_PATH), pull=True, tag=config.net_container_name())

    for log in logs:
        console.debug(log)

    console.info(f'network container \'{config.net_container_name()}\' built')
Example #7
0
    def _ensure_image_exists(self):
        """
            Ensures that an image exists if a plan has an inline
            dockerfile.
        """

        # if the plan does not have an inline dockerfile, then we can rely on
        # the call to run() later to pull the image instead.
        if not self.plan.has_dockerfile():
            return

        console.debug(f'checking if {self.plan.image_version()} is available')

        try:
            self.get_client().images.get(self.plan.image_version())
        except ImageNotFound as _:
            console.warn(
                f'image for plan [cyan]{self.plan.name}[/] does not exist, quickly building it'
            )

            dockerfile = BytesIO(self.plan.dockerfile.encode('utf-8'))
            console.debug(f'building dockerfile:\n{self.plan.dockerfile}')

            _, logs = self.get_client().images.build(
                fileobj=dockerfile,
                pull=True,
                tag=self.plan.image_version(),
                rm=True,
                forcerm=True)

            for log in logs:
                console.debug(log)

            console.info(
                f'container for [bold]{self.plan.image_version()}[/] built')
            self._ensure_net_exists()
Example #8
0
@network.command()
@click.argument('name')
@click.option('--outside', '-o', required=True, help='the outside, host port to open')
@click.option('--inside', '-i', required=True, help='the inside, container port to forward to')
def add(name, outside, inside):
    """
        Add a port to a plan
    """

    loader = Loader()
    if not (plan := loader.get_plan(name)):
        console.error(f'unable to find plan [bold]{name}[/]')
        return

    plan.container.run_net(outside, inside)
    console.info(f'port binding for {outside}->{plan.name}:{inside} created')


@network.command()
@click.argument('name')
@click.option('--outside', '-o', required=True, help='the outside, host port to open')
@click.option('--inside', '-i', required=True, help='the inside, container port to forward to')
def remove(name, outside, inside):
    """
        Removes a port mapping from a plan
    """

    loader = Loader()
    if not (plan := loader.get_plan(name)):
        console.error(f'unable to find plan [bold]{name}[/]')
        return
Example #9
0
@click.command(context_settings=dict(ignore_unknown_options=True, )
               )  # allow passing through options to the docker command
@click.argument('name')
@click.argument('extra_args', nargs=-1)
def run(name, extra_args):
    """
        Run a plan
    """

    loader = Loader()
    if not (plan := loader.get_plan(name)):
        console.error(f'unable to find plan [bold]{name}[/]')
        return

    console.info(f'found plan for [cyan]{name}[/]')
    if (c := len(plan.container.containers())) > 0:
        console.error(
            f'plan [bold]{name}[/] already has [b]{c}[/] containers running')
        console.info(
            f'use [bold]dwn show[/] to see running plans. [bold]dwn stop <plan>[/] to stop'
        )
        return

    plan.add_commands(extra_args) if extra_args else None

    for v, o in plan.volumes.items():
        console.info(f'volume: {v} -> {o["bind"]}')

    for m in plan.exposed_ports:
        console.info(f'port: {m[0]}<-{m[1]}')
Example #10
0
File: plans.py Project: vcont/dwn
def update(name):
    """
        Update plan images.
    """

    plan_targets = []

    if not name and not click.confirm('> a plan name was not specified, '
                                      'pull all valid plan images?'):
        return

    try:
        client = docker.from_env()
    except DockerException as e:
        console.error(f'failed to connect to docker: [bold]{e}[/e]')
        return

    loader = Loader()

    if name:
        plan_targets.append(loader.get_plan(name))
    else:
        [plan_targets.append(n) for n in loader.valid_plans()]

    for p in plan_targets:
        if p is None:
            continue

        try:
            # build the image if we have an inline dockerfile
            if p.has_dockerfile():
                console.info(f'building image [bold]{p.image_version()}[/]')
                dockerfile = BytesIO(p.dockerfile.encode('utf-8'))

                _, logs = client.images.build(fileobj=dockerfile,
                                              pull=True,
                                              tag=p.image_version(),
                                              rm=True,
                                              forcerm=True,
                                              nocache=True)
                for log in logs:
                    console.debug(log)

                console.info(
                    f'container for [bold]{p.image_version()}[/] built')

            # pull the image instead
            else:
                console.info(f'pulling image [bold]{p.image_version()}[/]')
                client.images.pull(p.image, tag=p.version)

        except ImageNotFound as e:
            console.error(f'failed to pull image: [bold]{e}[/]')
            continue
        except DockerException as e:
            console.error(f'a docker exception occurred: [bold]{e}[/]')
            continue

        console.info(
            f'image [bold]{p.image_version()}[/] for plan [cyan]{p.name}[/] updated'
        )