github.com/blystad/deis@v0.11.0/controller/api/tasks.py (about)

     1  """
     2  Long-running tasks for the Deis Controller API
     3  
     4  This module orchestrates the real "heavy lifting" of Deis, and as such these
     5  functions are decorated to run as asynchronous celery tasks.
     6  """
     7  
     8  from __future__ import unicode_literals
     9  
    10  import requests
    11  import threading
    12  
    13  from celery import task
    14  from docker.utils import utils
    15  from django.conf import settings
    16  
    17  
    18  @task
    19  def create_cluster(cluster):
    20      cluster._scheduler.setUp()
    21  
    22  
    23  @task
    24  def destroy_cluster(cluster):
    25      for app in cluster.app_set.all():
    26          app.destroy()
    27      cluster._scheduler.tearDown()
    28  
    29  
    30  @task
    31  def deploy_release(app, release):
    32      containers = app.container_set.all()
    33      threads = []
    34      for c in containers:
    35          threads.append(threading.Thread(target=c.deploy, args=(release,)))
    36      [t.start() for t in threads]
    37      [t.join() for t in threads]
    38  
    39  
    40  @task
    41  def import_repository(source, target_repository):
    42      """Imports an image from a remote registry into our own private registry"""
    43      data = {
    44          'src': source,
    45      }
    46      requests.post(
    47          '{}/v1/repositories/{}/tags'.format(settings.REGISTRY_URL,
    48                                              target_repository),
    49          data=data,
    50      )
    51  
    52  
    53  @task
    54  def start_containers(containers):
    55      create_threads = []
    56      start_threads = []
    57      for c in containers:
    58          create_threads.append(threading.Thread(target=c.create))
    59          start_threads.append(threading.Thread(target=c.start))
    60      [t.start() for t in create_threads]
    61      [t.join() for t in create_threads]
    62      [t.start() for t in start_threads]
    63      [t.join() for t in start_threads]
    64  
    65  
    66  @task
    67  def stop_containers(containers):
    68      destroy_threads = []
    69      delete_threads = []
    70      for c in containers:
    71          destroy_threads.append(threading.Thread(target=c.destroy))
    72          delete_threads.append(threading.Thread(target=c.delete))
    73      [t.start() for t in destroy_threads]
    74      [t.join() for t in destroy_threads]
    75      [t.start() for t in delete_threads]
    76      [t.join() for t in delete_threads]
    77  
    78  
    79  @task
    80  def run_command(c, command):
    81      release = c.release
    82      image = release.image + ':v' + str(release.version)
    83      # check for backwards compatibility
    84      if not _has_hostname(image):
    85          image = '{}:{}/{}'.format(settings.REGISTRY_HOST,
    86                                    settings.REGISTRY_PORT,
    87                                    release.image)
    88      try:
    89          # pull the image first
    90          rc, pull_output = c.run("docker pull {image}".format(**locals()))
    91          if rc != 0:
    92              raise EnvironmentError('Could not pull image: {image}'.format(**locals()))
    93          # run the command
    94          docker_args = ' '.join(['--entrypoint=/bin/bash',
    95                                  '-a', 'stdout', '-a', 'stderr', '--rm', image])
    96          escaped_command = command.replace("'", "'\\''")
    97          command = r"docker run {docker_args} -c \'{escaped_command}\'".format(**locals())
    98          return c.run(command)
    99      finally:
   100          c.delete()
   101  
   102  
   103  def _has_hostname(image):
   104      repo, tag = utils.parse_repository_tag(image)
   105      return True if '/' in repo and '.' in repo.split('/')[0] else False