Example #1
0
def api_containers(container=None):
    if container:
        (_, v) = utils.find_item(swarm.instance.containers, container)
        if v:
            if flask.request.authorization.username == 'admin':
                return flask.jsonify(v)
            else:
                v = copy.copy(v)
                v.pop('env', None)
                return flask.jsonify(v)
        else:
            return flask.Response('container "%s" not found' % container,
                                  status=404)
    else:
        if flask.request.args.get('full'):
            if flask.request.authorization.username == 'admin':
                return flask.jsonify(swarm.instance.containers)
            else:
                results = dict()
                for k, v in swarm.instance.containers.items():
                    results[k] = copy.copy(v)
                    results[k].pop('env', None)
                return flask.jsonify(results)
        else:
            results = {
                k: v['name']
                for k, v in swarm.instance.containers.items()
            }
            return flask.jsonify(results)
Example #2
0
def api_containers_stats(container, period):
    (k, _) = utils.find_item(swarm.instance.containers, container)
    if k:
        return get_stats(k, period)
    else:
        return flask.Response('container "%s" not found' % container,
                              status=404)
Example #3
0
def api_services_update(service):
    (k, _) = utils.find_item(swarm.instance.services, service)
    if k:
        swarm.instance.service_update(k)
        return flask.Response('service %s restarted' % service)
    else:
        return flask.Response('service "%s" not found' % service, status=404)
Example #4
0
def api_services(service=None):
    if service:
        (_, v) = utils.find_item(swarm.instance.services, service)
        if v:
            if flask.request.authorization.username == 'admin':
                return flask.jsonify(v)
            else:
                v = copy.copy(v)
                v.pop('env', None)
                return flask.jsonify(v)
        else:
            return flask.Response('service "%s" not found' % service,
                                  status=404)
    else:
        if flask.request.args.get('full'):
            if flask.request.authorization.username == 'admin':
                return flask.jsonify(swarm.instance.services)
            else:
                results = dict()
                for k, v in swarm.instance.services.items():
                    results[k] = copy.copy(v)
                    results[k].pop('env', None)
                return flask.jsonify(results)
        else:
            results = {
                k: v['name']
                for k, v in swarm.instance.services.items()
            }
            return flask.jsonify(results)
Example #5
0
    def container_log(self, container, lines=10, timestamps=False):
        if lines == 'all':
            lines = 100

        (k, v) = utils.find_item(self.containers, container)
        if not k:
            return None

        node = self.nodes[v['node']['id']]
        if 'url' in node:
            result = ""
            client = docker.APIClient(base_url=node['url'], version="auto", timeout=self.timeouts['docker'])
            try:
                log = client.logs(k, stdout=True, stderr=True, follow=False, timestamps=timestamps, tail=lines)
                if inspect.isgenerator(log):
                    for row in log:
                        # TODO work with generator
                        result += row.decode('utf-8')
                else:
                    result = log.decode('utf-8')
            except docker.errors.NotFound:
                self.logger.debug("Trying to get log from container '%s' that no longer exists." % container)
                result = "Countainer %s is no longer running." % container
        else:
            result = "Could not connect to docker host, no logs returned for %s." % container
        return result
Example #6
0
    def service_log(self, service, lines=10):
        (_, s) = utils.find_item(self.services, service)
        if not s:
            return None

        # TODO work with generator
        all_logs = []
        for c in s['containers']:
            for line in self.container_log(c['id'], lines, True).split("\n"):
                pieces = line.split(maxsplit=1)
                if len(pieces) == 2:
                    all_logs.append({'time': pieces[0], 'container': c['id'], 'log': pieces[1]})
        sorted_logs = sorted(all_logs, key=lambda x: x['time'])

        if lines != 'all':
            sorted_logs = sorted_logs[-lines:]

        log = ""
        for line in sorted_logs:
            log += "%s | %s | %s\n" % (line['time'], line['container'], line['log'])
        # for line in sorted_logs:
        #     pieces = line.split(maxsplit=1)
        #     if len(pieces) == 2:
        #         log += pieces[1] + "\n"

        return log
Example #7
0
 def service_remove(self, service):
     self.logger.info("remove service with name/id %s" % service)
     result = "successfully removed service " + service
     (k, v) = utils.find_item(self.services, service)
     removed = False
     if k:
         client = docker.APIClient(self.swarm_url, version='auto')
         try:
             removed = client.remove_service(k)
         except docker.errors.APIError:
             result = "failed to remove service" + service
     else:
         result = "failed to remove nonexistent service '%s'" % service
     if removed:
         # update in-memory storage.
         try:
             with self.lock:
                 self.swarm['services'].remove(k)
                 self.services.pop(k, None)
                 for container_id in v.containers:
                     self.containers.pop(container_id, None)
                 for node_id in v.nodes:
                     self.nodes.pop(node_id, None)
         except Exception as err:
             # it is fine to have exception here.
             self.logger.debug(err)
     return result
Example #8
0
def html_services_logs(service):
    """
    Return log viewer for a specific service.
    """
    (k, v) = utils.find_item(swarm.instance.services, service)
    return flask.render_template('logs.html',
                                 service_id=k,
                                 service_name=v['name'],
                                 containers=v['containers'])
Example #9
0
def api_services_restart(service):
    (k, v) = utils.find_item(swarm.instance.services, service)
    if k and v:
        replicas = v['replicas']['requested']
        api_services_scale(k, 0)
        time.sleep(30)
        api_services_scale(k, replicas)
        return flask.Response('service %s restarted' % service)
    else:
        return flask.Response('service "%s" not found' % service, status=404)
Example #10
0
def api_nodes(node):
    if node:
        (_, v) = utils.find_item(swarm.instance.nodes, node)
        if v:
            return flask.jsonify(v)
        else:
            return flask.Response('node "%s" not found' % node, status=404)
    else:
        if flask.request.args.get('full'):
            return flask.jsonify(swarm.instance.nodes)
        else:
            result = {k: v['name'] for k, v in swarm.instance.nodes.items()}
            return flask.jsonify(result)
Example #11
0
def api_nodes_stats(node, period):
    (k, _) = utils.find_item(swarm.instance.nodes, node)
    if k:
        return get_stats(k, period)
    else:
        return flask.Response('node "%s" not found' % node, status=404)
Example #12
0
def api_services_stats(service, period):
    (k, _) = utils.find_item(swarm.instance.services, service)
    if k:
        return get_stats(k, period)
    else:
        return flask.Response('service "%s" not found' % service, status=404)
Example #13
0
    def _service_update(self, service, force=False, **data):
        count = data.get("count", None)

        (k, v) = utils.find_item(self.services, service)
        if k:
            client = docker.APIClient(self.swarm_url, version='auto')
            s = client.inspect_service(k)
            if s and 'Spec' in s and 'TaskTemplate' in s['Spec']:
                spec = s['Spec']
                task = spec['TaskTemplate']

                config = task['ContainerSpec']
                image = config['Image']
                if force:
                    image = re.sub(r'@sha256.*', '', image)
                container_spec = docker.types.ContainerSpec(image,
                                                            command=config.get('Command', None),
                                                            args=config.get('Args', None),
                                                            hostname=config.get('Hostname', None),
                                                            env=config.get('Env', None),
                                                            workdir=config.get('Workdir', None),
                                                            user=config.get('User', None),
                                                            labels=config.get('Labels', None),
                                                            mounts=config.get('Mounts', None),
                                                            stop_grace_period=config.get('StopGracePeriod', None),
                                                            secrets=config.get('Secrets', None))

                if 'Resources' in task:
                    if 'Limits' in task['Resources']:
                        cpu_limit = task['Resources']['Limits'].get('NanoCPUs', None)
                        mem_limit = task['Resources']['Limits'].get('MemoryBytes', None)
                    else:
                        cpu_limit = None
                        mem_limit = None
                    if 'Reservations' in task['Resources']:
                        cpu_reservation = task['Resources']['Reservations'].get('NanoCPUs', None)
                        mem_reservation = task['Resources']['Reservations'].get('MemoryBytes', None)
                    else:
                        cpu_reservation = None
                        mem_reservation = None

                    resources = docker.types.Resources(cpu_limit, mem_limit, cpu_reservation, mem_reservation)
                else:
                    resources = None

                if 'RestartPolicy' in task:
                    config = task['RestartPolicy']
                    restart_policy = docker.types.RestartPolicy(condition=config.get('Condition', 'none'),
                                                                delay=config.get('Delay', 0),
                                                                max_attempts=config.get('MaxAttempts', 0),
                                                                window=config.get('Window', 0))
                else:
                    restart_policy = None

                if 'LogDriver' in task:
                    config = task['LogDriver']
                    log_driver = docker.types.DriverConfig(config['Name'],
                                                           options=config.get('Options', None))
                else:
                    log_driver = None

                force_update = task.get('ForceUpdate', 0)
                if force:
                    force_update += 1
                task_template = docker.types.TaskTemplate(container_spec,
                                                          resources=resources,
                                                          restart_policy=restart_policy,
                                                          placement=task.get('Placement', None),
                                                          log_driver=log_driver,
                                                          force_update=force_update)

                if count is not None:
                    mode = docker.types.ServiceMode("replicated", int(count))
                    # TODO bug in docker library, see https://github.com/docker/docker-py/issues/1572
                    if int(count) == 0:
                        mode.get('replicated')['Replicas'] = 0
                else:
                    mode = docker.types.ServiceMode("replicated", utils.get_item(spec, 'Mode.Replicated.Replicas', 0))

                if 'UpdateConfig' in spec:
                    config = spec['EndpointSpec']
                    update_config = docker.types.UpdateConfig(config.get('Parallelism', 0),
                                                              config.get('Delay', None),
                                                              config.get('FailureAction', 'continue'),
                                                              config.get('Monitor', None),
                                                              config.get('MaxFailureRatio', None))
                else:
                    update_config = None

                if 'EndpointSpec' in spec:
                    config = spec['EndpointSpec']
                    endpoint_spec = docker.types.EndpointSpec(config.get('Mode', None),
                                                              config.get('Ports', None))
                else:
                    endpoint_spec = None

                labels = spec.get('Labels', {})
                labels.update(data.get('labels', {}))
                if client.update_service(k,
                                         version=s['Version']['Index'],
                                         task_template=task_template,
                                         name=spec['Name'],
                                         labels=labels,
                                         mode=mode,
                                         update_config=update_config,
                                         networks=spec.get('Networks', None),
                                         endpoint_spec=endpoint_spec):
                    if count is not None:
                        v['replicas']['requested'] = int(count)
                    return True, 'OK'
                else:
                    return False, 'Could not update service %s.' % service

            else:
                return False, 'service "%s" not found' % service
        else:
            return False, 'service "%s" not found' % service