コード例 #1
0
 def deploy(self):
     CLI.info('Deploying...')
     self.clean()
     self.upload()
     self.pull()
     self.reload()
     self.logs()
     self.status()
コード例 #2
0
    def restart_proxy(self):
        CLI.info('Restarting proxy...')
        steps = 1

        CLI.step(1, steps, 'Reloading proxy container...')
        os.system(
            f'docker-compose {self.docker_ssh} -f configs/docker/docker-compose.{self.environment_id}.proxy.yml --project-name=reverse up -d'
        )
コード例 #3
0
 def pg_dump(self):
     now = datetime.datetime.now()
     # filename = now.strftime("%Y%m%d%H%M%S")
     filename = now.strftime(f"{self.PROJECT_NAME}_%Y%m%d_%H%M.pg")
     CLI.info(f'Backuping database into file {filename}')
     env = self.load_environment()
     os.system(
         f'docker {self.docker_ssh} exec -it {self.CONTAINER_DB} bash -c \'pg_dump -Fc -h {env["POSTGRES_HOST"]} -U {env["POSTGRES_USER"]} {env["POSTGRES_DBNAME"]} -W > /backups/{filename}\''
     )
コード例 #4
0
 def pg_restore(self, params):
     CLI.info(f'Restoring database from file {params}')
     CLI.underline(
         "Don't forget to drop database at first to prevent constraints collisions!"
     )
     env = self.load_environment()
     os.system(
         f'docker {self.docker_ssh} exec -it {self.CONTAINER_DB} bash -c \'pg_restore -h {env["POSTGRES_HOST"]} -U {env["POSTGRES_USER"]} -d {env["POSTGRES_DBNAME"]} -W < /backups/{params}\''
     )
コード例 #5
0
    def restart(self):
        CLI.info('Restarting...')
        steps = 4

        if self.SWARM:
            CLI.step(1, steps, 'Stopping and removing Docker app service...')

            for service in self.get_services():
                if service == self.CONTAINER_APP:
                    os.system(f'docker service rm {service}')

            CLI.step(2, steps, 'Recreating Docker swarm stack...')
            os.system(
                f'docker stack deploy -c configs/docker/{self.COMPOSE_PREFIX}.yml -c configs/docker/{self.COMPOSE_PREFIX}.{self.environment_id}.yml {self.PROJECT_NAME}'
            )

            CLI.step(
                3, steps,
                'Prune Docker images and volumes')  # todo prune on every node
            os.system(
                f'docker {self.docker_ssh} system prune --volumes --force')

            CLI.step(4, steps,
                     'Collecting static files')  # todo collect static
            app_container = self.get_containers_starts_with(self.CONTAINER_APP)

            if app_container:
                os.system(
                    f'docker {self.docker_ssh} exec -i {app_container[0]} python manage.py collectstatic --noinput --verbosity 0'
                )

        else:
            CLI.step(1, steps, 'Stopping and removing Docker containers...')

            for service in self.config['containers']['deploy'][
                    'zero_downtime'] + self.config['containers']['deploy'][
                        'restart']:
                container = self.get_container_name(service)
                os.popen(f'docker {self.docker_ssh} container stop {container}'
                         ).read()
                os.system(f'docker {self.docker_ssh} container rm {container}')

            CLI.step(2, steps, 'Recreating Docker containers...')
            os.system(
                f'docker-compose {self.docker_ssh} -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.yml -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.{self.environment_id}.yml --project-name={self.PROJECT_NAME} up -d'
            )
            # os.system(f'docker-compose {self.docker_ssh} -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.yml -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.{self.environment_id}.yml --project-name={self.PROJECT_NAME} up --remove-orphans -d')

            CLI.step(3, steps, 'Prune Docker images and volumes')
            os.system(
                f'docker {self.docker_ssh} system prune --volumes --force')

            CLI.step(4, steps, 'Collecting static files')
            os.system(
                f'docker {self.docker_ssh} exec -i {self.CONTAINER_APP} python manage.py collectstatic --noinput --verbosity 0'
            )
コード例 #6
0
    def upload(self, context='services'):
        CLI.info('Uploading...')
        steps = 1

        if context == 'services':
            CLI.step(
                1, steps,
                'Uploading configs for context "services" [webserver, cache, htpasswd]'
            )
        elif context == 'compose':
            CLI.step(
                1, steps,
                'Uploading configs for context "compose" [docker compose configs and environment]'
            )
        elif context == 'mantis':
            CLI.step(1, steps, 'Uploading configs for mantis [mantis.json]')
        else:
            CLI.error(f'Unknown context "{context}"')

        if self.environment_id == 'dev':
            print('Skipping for dev...')
        elif self.mode == 'host':
            CLI.warning(
                'Not uploading due to host mode! Be sure your configs on host are up to date!'
            )
        else:
            if context == 'services':
                os.system(
                    f'rsync -arvz -e \'ssh -p {self.port}\' -rvzh --progress {self.cache_config} {self.user}@{self.host}:/home/{self.user}/public_html/web/configs/{self.CACHE}/'
                )
                os.system(
                    f'rsync -arvz -e \'ssh -p {self.port}\' -rvzh --progress {self.webserver_config} {self.user}@{self.host}:/home/{self.user}/public_html/web/configs/{self.WEBSERVER}/'
                )
                os.system(
                    f'rsync -arvz -e \'ssh -p {self.port}\' -rvzh --progress {self.webserver_config_proxy} {self.user}@{self.host}:/etc/nginx/conf.d/proxy/'
                )
                os.system(
                    f'rsync -arvz -e \'ssh -p {self.port}\' -rvzh --progress {self.htpasswd} {self.user}@{self.host}:/etc/nginx/conf.d/'
                )

            elif context == 'mantis':
                os.system(
                    f'rsync -arvz -e \'ssh -p {self.port}\' -rvzh --progress {self.config_file} {self.user}@{self.host}:/home/{self.user}/public_html/web/configs/'
                )

            elif context == 'compose':
                os.system(
                    f'rsync -arvz -e \'ssh -p {self.port}\' -rvzh --progress {self.environment_file} {self.user}@{self.host}:/home/{self.user}/public_html/web/configs/environments/'
                )

                for config in self.compose_configs:
                    os.system(
                        f'rsync -arvz -e \'ssh -p {self.port}\' -rvzh --progress {config} {self.user}@{self.host}:/home/{self.user}/public_html/web/configs/docker/'
                    )
コード例 #7
0
    def push(self):
        CLI.info(f'Pushing...')

        steps = 2
        CLI.step(1, steps, 'Tagging Docker image...')
        os.system(
            f'docker tag {self.IMAGE_NAME} {self.DOCKER_REPOSITORY}:{self.DOCKER_TAG}'
        )
        print(
            f'Successfully tagged {self.DOCKER_REPOSITORY}:{self.DOCKER_TAG}')

        CLI.step(2, steps, 'Pushing Docker image...')
        os.system(f'docker push {self.DOCKER_REPOSITORY}:{self.DOCKER_TAG}')
コード例 #8
0
    def status(self):
        if self.SWARM:  # todo remove containers as well ?
            CLI.info('Getting status...')
            os.system(f'docker stack services {self.PROJECT_NAME}')

        else:
            CLI.info('Getting status...')
            steps = 2

            CLI.step(1, steps, 'List of Docker images')
            os.system(f'docker {self.docker_ssh} image ls')

            CLI.step(2, steps, 'Docker containers')
            os.system(f'docker {self.docker_ssh} container ls -a --size')
コード例 #9
0
    def remove(self, params=''):
        if self.SWARM:  # todo remove containers as well ?
            CLI.info('Removing services...')
            os.system(f'docker stack rm {self.PROJECT_NAME}')

        else:
            CLI.info('Removing containers...')

            containers = self.get_containers(
            ) if params == '' else params.split(' ')

            steps = len(containers)

            for index, container in enumerate(containers):
                CLI.step(index + 1, steps, f'Removing {container}')
                os.system(f'docker {self.docker_ssh} container rm {container}')
コード例 #10
0
    def stop(self, params=None):
        if self.SWARM:  # todo can stop service ?
            CLI.info('Removing services...')
            os.system(f'docker stack rm {self.PROJECT_NAME}')

        else:
            CLI.info('Stopping containers...')

            containers = self.get_containers() if not params else params.split(
                ' ')

            steps = len(containers)

            for index, container in enumerate(containers):
                CLI.step(index + 1, steps, f'Stopping {container}')
                os.system(
                    f'docker {self.docker_ssh} container stop {container}')
コード例 #11
0
    def start(self, params):
        if self.SWARM:
            CLI.info('Starting services...')
            os.system(
                f'docker stack deploy -c configs/docker/{self.COMPOSE_PREFIX}.yml -c configs/docker/{self.COMPOSE_PREFIX}.{self.environment_id}.yml {self.PROJECT_NAME}'
            )

        else:
            CLI.info('Starting containers...')

            containers = self.get_containers() if not params else params.split(
                ' ')

            steps = len(containers)

            for index, container in enumerate(containers):
                CLI.step(index + 1, steps, f'Starting {container}')
                os.system(
                    f'docker {self.docker_ssh} container start {container}')
コード例 #12
0
    def logs(self, params=None):
        if self.SWARM:
            CLI.info('Reading logs...')

            services = params.split(' ') if params else self.get_services()
            lines = '-f' if params else '--tail 10'
            steps = len(services)

            for index, service in enumerate(services):
                CLI.step(index + 1, steps, f'{service} logs')
                os.system(f'docker service logs {service} {lines}')

        else:
            CLI.info('Reading logs...')

            containers = params.split(' ') if params else self.get_containers()
            lines = '-f' if params else '--tail 10'
            steps = len(containers)

            for index, container in enumerate(containers):
                CLI.step(index + 1, steps, f'{container} logs')
                os.system(f'docker {self.docker_ssh} logs {container} {lines}')
コード例 #13
0
    def networks(self):
        # todo for swarm
        CLI.info('Getting networks...')
        steps = 1

        CLI.step(1, steps, 'List of Docker networks')

        networks = os.popen(f'docker {self.docker_ssh} network ls').read()
        networks = networks.strip().split('\n')

        for index, network in enumerate(networks):
            network_data = list(filter(lambda x: x != '', network.split(' ')))
            network_name = network_data[1]

            if index == 0:
                print(f'{network}\tCONTAINERS')
            else:
                containers = os.popen(
                    f'docker {self.docker_ssh} network inspect -f \'{{{{ range $key, $value := .Containers }}}}{{{{ .Name }}}} {{{{ end }}}}\' {network_name}'
                ).read()
                containers = ', '.join(containers.split())
                print(f'{network}\t{containers}'.strip())
コード例 #14
0
    def build(self, params=''):
        CLI.info(f'Building...')
        CLI.info(f'Params = {params}')
        CLI.info(f'Dockerfile = {self.configs_path}/docker/{self.DOCKER_FILE}')
        steps = 1

        CLI.step(1, steps, 'Building Docker image...')

        build_args = self.config['build']['args']
        build_args = ','.join(map('='.join, build_args.items()))
        build_kit = self.config['build']['kit']
        build_kit = 'DOCKER_BUILDKIT=1' if build_kit else ''

        if build_args != '':
            build_args = build_args.split(',')
            build_args = [f'--build-arg {arg}' for arg in build_args]
            build_args = ' '.join(build_args)

        CLI.info(f'Kit = {build_kit}')
        CLI.info(f'Args = {build_args}')

        os.system(
            f'time {build_kit} docker build . {build_args} -t {self.IMAGE_NAME} -f {self.configs_path}/docker/{self.DOCKER_FILE} {params}'
        )
コード例 #15
0
 def send_test_email(self):
     CLI.info('Sending test email...')
     os.system(
         f'docker {self.docker_ssh} exec -i {self.CONTAINER_APP} python manage.py sendtestemail --admins'
     )
コード例 #16
0
    def reload(self):  # todo deploy swarm
        CLI.info('Reloading containers...')
        zero_downtime_services = self.config['containers']['deploy'][
            'zero_downtime']
        restart_services = self.config['containers']['deploy']['restart']

        steps = 5

        step = 1
        CLI.step(step, steps,
                 f'Zero downtime services: {zero_downtime_services}')

        for service in zero_downtime_services:
            container = self.get_container_name(service)
            os.system(
                f'docker-compose {self.docker_ssh} -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.yml -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.{self.environment_id}.yml --project-name={self.PROJECT_NAME} run -d --service-ports --name={container}_new {service}'
            )
            CLI.info(f'Renaming old container [{container}_old]...')

            if container in self.get_containers():
                os.system(
                    f'docker {self.docker_ssh} container rename {container} {container}_old'
                )
            else:
                CLI.info(f'{container}_old was not running')

            CLI.info(f'Renaming new container [{container}]...')
            os.system(
                f'docker {self.docker_ssh} container rename {container}_new {container}'
            )

        step += 1
        CLI.step(step, steps, 'Collecting static files')
        os.system(
            f'docker {self.docker_ssh} exec -i {self.CONTAINER_APP} python manage.py collectstatic --noinput --verbosity 0'
        )

        step += 1
        CLI.step(step, steps, 'Reloading webserver...')
        os.system(
            f'docker {self.docker_ssh} exec -it {self.CONTAINER_WEBSERVER} {self.WEBSERVER} -s reload'
        )

        step += 1
        CLI.step(
            step, steps,
            f'Stopping old zero downtime services: {zero_downtime_services}')

        for service in zero_downtime_services:
            container = self.get_container_name(service)

            if container in self.get_containers():
                CLI.info(f'Stopping old container [{container}_old]...')
                os.system(
                    f'docker {self.docker_ssh} container stop {container}_old')

                CLI.info(f'Removing old container [{container}_old]...')
                os.system(
                    f'docker {self.docker_ssh} container rm {container}_old')
            else:
                CLI.info(f'{container}_old was not running')

        step += 1
        CLI.step(step, steps, f'Restart services: {restart_services}')

        for service in restart_services:
            container = self.get_container_name(service)

            CLI.underline(f'Recreating {service} container ({container})...')

            if container in self.get_containers():
                CLI.info(f'Stopping container [{container}]...')
                os.system(
                    f'docker {self.docker_ssh} container stop {container}')

                CLI.info(f'Removing container [{container}]...')
                os.system(f'docker {self.docker_ssh} container rm {container}')

                CLI.info(f'Creating new container [{container}]...')
                os.system(
                    f'docker-compose {self.docker_ssh} -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.yml -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.{self.environment_id}.yml --project-name={self.PROJECT_NAME} run -d --service-ports --name={container} {service}'
                )
            else:
                CLI.info(f'{container} was not running')
コード例 #17
0
 def exec(self, params):
     container, command = params.split(' ', maxsplit=1)
     CLI.info(f'Executing command "{command}" in container {container}...')
     os.system(f'docker {self.docker_ssh} exec -it {container} {command}')
コード例 #18
0
 def psql(self):
     CLI.info('Starting psql...')
     env = self.load_environment()
     os.system(
         f'docker {self.docker_ssh} exec -it {self.CONTAINER_DB} psql -h {env["POSTGRES_HOST"]} -U {env["POSTGRES_USER"]} -d {env["POSTGRES_DBNAME"]} -W'
     )
コード例 #19
0
 def manage(self, params):
     CLI.info('Django manage...')
     os.system(
         f'docker {self.docker_ssh} exec -ti {self.CONTAINER_APP} python manage.py {params}'
     )
コード例 #20
0
 def ssh(self, params):
     CLI.info('Logging to container...')
     os.system(f'docker {self.docker_ssh} exec -it {params} /bin/sh')
コード例 #21
0
 def shell(self):
     CLI.info('Connecting to Django shell...')
     os.system(
         f'docker {self.docker_ssh} exec -i {self.CONTAINER_APP} python manage.py shell'
     )
コード例 #22
0
 def pull(self):
     CLI.info('Pulling docker image...')
     os.system(
         f'docker-compose {self.docker_ssh} -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.yml -f {self.configs_path}/docker/{self.COMPOSE_PREFIX}.{self.environment_id}.yml pull'
     )
コード例 #23
0
 def reload_webserver(self):
     CLI.info('Reloading webserver...')
     os.system(
         f'docker {self.docker_ssh} exec -it {self.CONTAINER_WEBSERVER} {self.WEBSERVER} -s reload'
     )
コード例 #24
0
    def clean(self):  # todo clean on all nodes
        CLI.info('Cleaning...')
        steps = 1

        CLI.step(1, steps, 'Prune Docker images and volumes')
        os.system(f'docker {self.docker_ssh} system prune --volumes --force')