aboutsummaryrefslogtreecommitdiffstats
path: root/api/resources/v2/tasks.py
blob: 25a9cf109e5376e05541c8c82bd75a875d457ca5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
Project: OPNFV documentation project (opnfvdocs)
Project Creation Date: March 31, 2015
Project Category: Documentation
Lifecycle State: Incubation
Primary Contact: Sofia Wallin (sofia.wallin@ericsson.com)
Project Lead: Sofia Wallin (sofia.wallin@ericsson.com)
Jira Project Name: OPNFV documentation project
Jira Project Prefix: DOCS
Mailing list tag: [docs]
IRC: Server:freenode.net Channel:#opnfv
Repository: opnfvdocs

Committers:
christopher.price@ericsson.com
fatih.degirmenci@ericsson.com
Iben.Rodriguez@spirent.com
r-mibu@cq.jp.nec.com
sofia.wallin@ericsson.com

Link to TSC approval of the project: http://ircbot.wl.linuxfoundation.org/meetings/opnfv-meeting/2015/opnfv-meeting.2015-03-31-13.56.html
Link(s) to approval of additional committers:
* Approval of Victor Laza as a committer: http://lists.opnfv.org/pipermail/opnfv-tsc/2015-April/000747.html
* Approval of Ryota Mibu as a committer: http://lists.opnfv.org/pipermail/opnfv-tsc/2016-January/001777.html
* Approval of Sofia Wallin as a committer: http://lists.opnfv.org/pipermail/opnfv-tsc/2016-January/001778.html
href='#n254'>254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
##############################################################################
# Copyright (c) 2017 Huawei Technologies Co.,Ltd.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
import uuid
import logging
import os
import errno
from datetime import datetime

from oslo_serialization import jsonutils

from api import ApiResource
from api.database.v2.handlers import V2TaskHandler
from api.database.v2.handlers import V2ProjectHandler
from api.database.v2.handlers import V2EnvironmentHandler
from api.utils.thread import TaskThread
from yardstick.common.utils import result_handler
from yardstick.common.utils import change_obj_to_dict
from yardstick.common import constants as consts
from yardstick.benchmark.core.task import Task
from yardstick.benchmark.core import Param

LOG = logging.getLogger(__name__)
LOG.setLevel(logging.DEBUG)


class V2Tasks(ApiResource):

    def get(self):
        task_handler = V2TaskHandler()
        tasks = [change_obj_to_dict(t) for t in task_handler.list_all()]

        for t in tasks:
            result = t['result']
            t['result'] = jsonutils.loads(result) if result else None

        return result_handler(consts.API_SUCCESS, {'tasks': tasks})

    def post(self):
        return self._dispatch_post()

    def create_task(self, args):
        try:
            name = args['name']
        except KeyError:
            return result_handler(consts.API_ERROR, 'name must be provided')

        try:
            project_id = args['project_id']
        except KeyError:
            return result_handler(consts.API_ERROR, 'project_id must be provided')

        task_id = str(uuid.uuid4())
        create_time = datetime.now()
        task_handler = V2TaskHandler()

        LOG.info('create task in database')
        task_init_data = {
            'uuid': task_id,
            'project_id': project_id,
            'name': name,
            'time': create_time,
            'status': -1
        }
        task_handler.insert(task_init_data)

        LOG.info('create task in project')
        project_handler = V2ProjectHandler()
        project_handler.append_attr(project_id, {'tasks': task_id})

        return result_handler(consts.API_SUCCESS, {'uuid': task_id})


class V2Task(ApiResource):

    def get(self, task_id):
        try:
            uuid.UUID(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'invalid task id')

        task_handler = V2TaskHandler()
        try:
            task = task_handler.get_by_uuid(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'no such task id')

        task_info = change_obj_to_dict(task)
        result = task_info['result']
        task_info['result'] = jsonutils.loads(result) if result else None

        return result_handler(consts.API_SUCCESS, {'task': task_info})

    def delete(self, task_id):
        try:
            uuid.UUID(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'invalid task id')

        task_handler = V2TaskHandler()
        try:
            project_id = task_handler.get_by_uuid(task_id).project_id
        except ValueError:
            return result_handler(consts.API_ERROR, 'no such task id')

        LOG.info('delete task in database')
        task_handler.delete_by_uuid(task_id)

        project_handler = V2ProjectHandler()
        project = project_handler.get_by_uuid(project_id)

        if project.tasks:
            LOG.info('update tasks in project')
            new_task_list = project.tasks.split(',')
            new_task_list.remove(task_id)
            if new_task_list:
                new_tasks = ','.join(new_task_list)
            else:
                new_tasks = None
            project_handler.update_attr(project_id, {'tasks': new_tasks})

        return result_handler(consts.API_SUCCESS, {'task': task_id})

    def put(self, task_id):

        try:
            uuid.UUID(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'invalid task id')

        task_handler = V2TaskHandler()
        try:
            task_handler.get_by_uuid(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'no such task id')

        return self._dispatch_post(task_id=task_id)

    def add_environment(self, args):

        task_id = args['task_id']
        try:
            environment_id = args['environment_id']
        except KeyError:
            return result_handler(consts.API_ERROR, 'environment_id must be provided')

        try:
            uuid.UUID(environment_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'invalid environment id')

        environment_handler = V2EnvironmentHandler()
        try:
            environment_handler.get_by_uuid(environment_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'no such environment id')

        LOG.info('update environment_id in task')
        task_handler = V2TaskHandler()
        task_handler.update_attr(task_id, {'environment_id': environment_id})

        return result_handler(consts.API_SUCCESS, {'uuid': task_id})

    def add_case(self, args):
        task_id = args['task_id']
        try:
            name = args['case_name']
        except KeyError:
            return result_handler(consts.API_ERROR, 'case_name must be provided')

        try:
            content = args['case_content']
        except KeyError:
            return result_handler(consts.API_ERROR, 'case_content must be provided')

        LOG.info('update case info in task')
        task_handler = V2TaskHandler()
        task_update_data = {
            'case_name': name,
            'content': content,
            'suite': False
        }
        task_handler.update_attr(task_id, task_update_data)

        return result_handler(consts.API_SUCCESS, {'uuid': task_id})

    def add_suite(self, args):
        task_id = args['task_id']
        try:
            name = args['suite_name']
        except KeyError:
            return result_handler(consts.API_ERROR, 'suite_name must be provided')

        try:
            content = args['suite_content']
        except KeyError:
            return result_handler(consts.API_ERROR, 'suite_content must be provided')

        LOG.info('update suite info in task')
        task_handler = V2TaskHandler()
        task_update_data = {
            'case_name': name,
            'content': content,
            'suite': True
        }
        task_handler.update_attr(task_id, task_update_data)

        return result_handler(consts.API_SUCCESS, {'uuid': task_id})

    def run(self, args):
        try:
            task_id = args['task_id']
        except KeyError:
            return result_handler(consts.API_ERROR, 'task_id must be provided')

        try:
            uuid.UUID(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'invalid task id')

        task_handler = V2TaskHandler()
        try:
            task = task_handler.get_by_uuid(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'no such task id')

        if not task.environment_id:
            return result_handler(consts.API_ERROR, 'environment not set')

        if not task.case_name or not task.content:
            return result_handler(consts.API_ERROR, 'case not set')

        if task.status == 0:
            return result_handler(consts.API_ERROR, 'task is already running')

        with open('/tmp/{}.yaml'.format(task.case_name), 'w') as f:
            f.write(task.content)

        data = {
            'inputfile': ['/tmp/{}.yaml'.format(task.case_name)],
            'task_id': task_id
        }
        if task.suite:
            data.update({'suite': True})

        LOG.info('start task thread')
        param = Param(data)
        task_thread = TaskThread(Task().start, param, task_handler)
        task_thread.start()

        return result_handler(consts.API_SUCCESS, {'uuid': task_id})


class V2TaskLog(ApiResource):

    def get(self, task_id):
        try:
            uuid.UUID(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'invalid task id')

        task_handler = V2TaskHandler()
        try:
            task = task_handler.get_by_uuid(task_id)
        except ValueError:
            return result_handler(consts.API_ERROR, 'no such task id')

        index = int(self._get_args().get('index', 0))

        try:
            with open(os.path.join(consts.TASK_LOG_DIR, '{}.log'.format(task_id))) as f:
                f.seek(index)
                data = f.readlines()
                index = f.tell()
        except OSError as e:
            if e.errno == errno.ENOENT:
                return result_handler(consts.API_ERROR, 'log file does not exist')
            return result_handler(consts.API_ERROR, 'error with log file')

        return_data = {
            'index': index,
            'data': data
        }

        return result_handler(task.status, return_data)