from fabric.api import env, task from fabric.contrib.files import upload_template import os import sys import pathlib dir_parent = pathlib.Path(os.path.abspath(__file__)).parents[2] sys.path.append(str(dir_parent)) try: from customfabric.modules.utils import loggify, booleanize from customfabric.modules.utils import generate_template_files_path from customfabric.modules.utils import generate_template_build_path from customfabric.modules.utils import executize, print_console except ImportError: raise # from .utils import loggify, generate_template_files_path, booleanize # from .utils import generate_template_build_path, print_console # from .utils import executize @task def docker_ip(): configuration = env.config # in the configuration file under docker,database, if host is set to local # use docker-machine, because it means we are probably on OSX # # otherwise, if host is set to anything else (like the actual ip) then just # return the host ip address that we set in configuration if configuration.docker.database.host == 'local': # docker_cmd = 'docker-machine ip %s' % \ # configuration.docker.machine # docker_cmd = "docker inspect -f '{{" # docker_cmd += "range.NetworkSettings.Networks}}" # docker_cmd += "{{.IPAddress}}{{end}}' pedantic_tu" # _execute = executize("run") # return _execute(docker_cmd) return "localhost" else: return configuration.docker.database.host def docker_run(cmd): configuration = env.config if env.debug: logger = loggify("docker", 'create') # use executize to return either the methods sudo or run from # fabric.operations # # we are checking to see if the host is local or not # if it is local, that means OSX, which means the user can directly run any # docker commands, but if it is remote, it probably requires sudo to run # docker commands _execute = executize("run") if configuration.docker.database.host != 'local': _execute = executize("sudo") if env.debug: logger.debug("_execute(cmd): %s" % cmd) else: _execute(cmd) @task def generate(): """ generates and uploads the docker.yml configuration file based on the settings in the yml file for the current branch. e.g. if we are using development.yml then it will check for the docker settings in there to find out what conf values we want to use when creating whatever docker containers we are usign for this branch currently, only the development branch is using docker, but I might change that in the future. """ configuration = env.config if env.debug: logger = loggify('docker', 'generate') build_path = generate_template_build_path('docker', 'database') files_path = generate_template_files_path('docker') context = dict() context['docker_service_name'] = \ configuration.docker.database.service_name context['docker_container_name'] = \ configuration.docker.database.container_name context['docker_database_env_user'] = \ configuration.docker.database.env.user context['docker_database_env_pass'] = \ configuration.docker.database.env.password context['docker_database_env_db'] = \ configuration.docker.database.env.dbname context['docker_database_image'] = configuration.docker.database.image context['docker_database_port_external'] = \ configuration.server.database.port context['docker_database_port_internal'] = \ configuration.docker.database.port context['projectbranch'] = configuration.project.branch context['database_user'] = configuration.server.database.admin.user context['database_pass'] = configuration.server.database.admin.password context['database_name'] = configuration.server.database.name if hasattr(configuration.docker.database, 'volumes') and \ hasattr(configuration.docker.database.volumes, 'data'): context['docker_volume_data_external'] = \ configuration.docker.database.volumes.data.external context['docker_volume_data_internal'] = \ configuration.docker.database.volumes.data.internal if env.debug: for key in context.keys(): logger.debug("context[{key}] : {value}".format( key=key, value=context[key])) upload_msg = "upload_template(" \ "\n\tfilename={filename}," \ "\n\tdestination={destination}," \ "\n\tcontext={context}," \ "\n\tuse_jinja=True," \ "\n\tuse_sudo=False," \ "\n\tbackup=False," \ "\n\ttemplate_dir={template_dir})".format( filename=configuration.templates.docker.database.src, destination=build_path, context=context, template_dir=files_path) logger.debug("upload_msg : %s" % upload_msg) import pprint pp = pprint.PrettyPrinter(indent=4) print("context:\n") pp.pprint(context) else: config_src = configuration.templates.docker.database.src upload_template( filename=config_src, destination=build_path, context=context, use_jinja=True, use_sudo=False, backup=False, template_dir=files_path) @task def create(container='database'): """ helper function to create a docker-based database container container - specifies the type of container being built NOTE: "container" must have a corresponding value in configuration file """ configuration = env.config if env.debug: logger = loggify("docker", 'create') build_path = generate_template_build_path('docker', container) info_msg = """ Generating container template for {container}, note that the container paramter of "{container}" must have a corresponding value in the {branch} configuration file under "docker" """.format(container=container, branch="dev") print_console(info_msg, numsep=60) docker_service_name = configuration.docker.database.service_name dockercompose_cmd = \ "docker compose -f {build_path} up -d {docker_service_name}".format( build_path=build_path, docker_service_name=docker_service_name ) if env.debug: logger.debug("build_path : %s" % build_path) logger.debug("dockercompose_cmd : %s" % dockercompose_cmd) logger.debug("docker_service_name : %s" % docker_service_name) else: docker_run(dockercompose_cmd) @task def status(): docker_run("docker ps -a") @task def start(create=False): """ this will start the docker container referenced by container_type NOTE: you should have created it with the docker.create method above first! container_type - the type of container to start create - craete if container has not yet been created """ if env.debug: logger = loggify("docker", 'create') configuration = env.config create = booleanize(create) docker_start = 'docker start %s' % \ configuration.docker.database.container_name if env.debug: logger.debug("docker_run(%s)" % docker_start) docker_run(docker_start) else: docker_run(docker_start) @task def stop(remove=False): """ remove=False this will start the docker container referenced by container_type NOTE: you should have created it with the docker.create method above first! container_type - the type of container to start create - craete if container has not yet been created """ configuration = env.config remove = booleanize(remove) docker_stop = 'docker stop %s' % \ configuration.docker.database.container_name docker_rm = 'docker rm %s' % configuration.docker.database.container_name if env.debug: print("docker_run(%s)" % docker_stop) print("docker_run(%s)" % docker_rm) else: docker_run(docker_stop) if remove: docker_run(docker_rm) @task def edit(param='help'): """ calls up mvim on the docker conf and build files """ from .maintenance import edit as maintenance_edit configuration = env.config print('keys: %s' % configuration.templates.docker.keys()) print('path: %s' % configuration.templates.docker.path.keys()) print('path.remote: %s' % configuration.templates.docker.path.remote) print('path.local: %s' % configuration.templates.docker.path.local) print('database: %s' % configuration.templates.docker.database.keys()) print('database.src: %s' % configuration.templates.docker.database.src) print('database.dst: %s' % configuration.templates.docker.database.dst) import os database_build_path = os.path.join( configuration.templates.docker.path.remote, 'build', configuration.templates.docker.database.dst ) database_template_path = os.path.join( configuration.templates.docker.path.remote, 'files', configuration.templates.docker.database.src ) print('database build path: %s' % database_build_path) print('database template path: %s' % database_template_path) project_branch = configuration.project.branch print('project branch: %s' % project_branch) locations = { 'database': { 'path': database_build_path, 'desc': 'docker database file in scripts/conf/docker/build', }, 'template': { 'path': database_template_path, 'desc': 'docker template file for database is' 'scripts/conf/docker/files', } } if param in locations.keys(): remote_path = locations[param]['path'] maintenance_edit(remote_path=remote_path) else: # if param == 'help': print(""" "fab docker.edit" automates editing template configuration files for docker database to use this you must pass one of the editable locations in as a parameter currently editable locations are: """) for k_loc in locations.keys(): print("\t{0: <20} - {1}".format(k_loc, locations[k_loc]['desc'])) return