fabric/modules/docker.py

314 lines
9 KiB
Python

from fabric.api import env, task
from fabric.contrib.files import upload_template
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
_execute = executize("run")
# 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
return _execute(docker_cmd)
else:
return configuration.docker.database.host
def docker_run(cmd):
from fabric.context_managers import prefix
configuration = env.config
# 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 configuration.docker.machine:
docker_eval = "eval $(docker-machine env %s)" % \
configuration.docker.machine
with prefix(docker_eval):
_execute(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 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)
dockercompose_cmd = \
"docker-compose -f {build_path} up -d".format(build_path=build_path)
if env.debug:
logger.debug("build_path : %s" % build_path)
logger.debug("dockercompose_cmd : %s" % dockercompose_cmd)
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
"""
configuration = env.config
create = booleanize(create)
docker_start = 'docker start %s' % \
configuration.docker.database.container_name
if env.debug:
print("docker_run(%s)" % 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
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