Merge "Testing live migration using qemu"
[yardstick.git] / api / resources / v2 / tasks.py
1 ##############################################################################
2 # Copyright (c) 2017 Huawei Technologies Co.,Ltd.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import uuid
10 import logging
11 from datetime import datetime
12
13 from oslo_serialization import jsonutils
14
15 from api import ApiResource
16 from api.database.v2.handlers import V2TaskHandler
17 from api.database.v2.handlers import V2ProjectHandler
18 from api.database.v2.handlers import V2EnvironmentHandler
19 from api.utils.thread import TaskThread
20 from yardstick.common.utils import result_handler
21 from yardstick.common.utils import change_obj_to_dict
22 from yardstick.common import constants as consts
23 from yardstick.benchmark.core.task import Task
24 from yardstick.benchmark.core import Param
25
26 LOG = logging.getLogger(__name__)
27 LOG.setLevel(logging.DEBUG)
28
29
30 class V2Tasks(ApiResource):
31
32     def get(self):
33         task_handler = V2TaskHandler()
34         tasks = [change_obj_to_dict(t) for t in task_handler.list_all()]
35
36         for t in tasks:
37             result = t['result']
38             t['result'] = jsonutils.loads(result) if result else None
39
40         return result_handler(consts.API_SUCCESS, {'tasks': tasks})
41
42     def post(self):
43         return self._dispatch_post()
44
45     def create_task(self, args):
46         try:
47             name = args['name']
48         except KeyError:
49             return result_handler(consts.API_ERROR, 'name must be provided')
50
51         try:
52             project_id = args['project_id']
53         except KeyError:
54             return result_handler(consts.API_ERROR, 'project_id must be provided')
55
56         task_id = str(uuid.uuid4())
57         create_time = datetime.now()
58         task_handler = V2TaskHandler()
59
60         LOG.info('create task in database')
61         task_init_data = {
62             'uuid': task_id,
63             'project_id': project_id,
64             'name': name,
65             'time': create_time,
66             'status': -1
67         }
68         task_handler.insert(task_init_data)
69
70         LOG.info('create task in project')
71         project_handler = V2ProjectHandler()
72         project_handler.append_attr(project_id, {'tasks': task_id})
73
74         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
75
76
77 class V2Task(ApiResource):
78
79     def get(self, task_id):
80         try:
81             uuid.UUID(task_id)
82         except ValueError:
83             return result_handler(consts.API_ERROR, 'invalid task id')
84
85         task_handler = V2TaskHandler()
86         try:
87             task = task_handler.get_by_uuid(task_id)
88         except ValueError:
89             return result_handler(consts.API_ERROR, 'no such task id')
90
91         task_info = change_obj_to_dict(task)
92         result = task_info['result']
93         task_info['result'] = jsonutils.loads(result) if result else None
94
95         return result_handler(consts.API_SUCCESS, {'task': task_info})
96
97     def delete(self, task_id):
98         try:
99             uuid.UUID(task_id)
100         except ValueError:
101             return result_handler(consts.API_ERROR, 'invalid task id')
102
103         task_handler = V2TaskHandler()
104         try:
105             project_id = task_handler.get_by_uuid(task_id).project_id
106         except ValueError:
107             return result_handler(consts.API_ERROR, 'no such task id')
108
109         LOG.info('delete task in database')
110         task_handler.delete_by_uuid(task_id)
111
112         project_handler = V2ProjectHandler()
113         project = project_handler.get_by_uuid(project_id)
114
115         if project.tasks:
116             LOG.info('update tasks in project')
117             new_task_list = project.tasks.split(',')
118             new_task_list.remove(task_id)
119             if new_task_list:
120                 new_tasks = ','.join(new_task_list)
121             else:
122                 new_tasks = None
123             project_handler.update_attr(project_id, {'tasks': new_tasks})
124
125         return result_handler(consts.API_SUCCESS, {'task': task_id})
126
127     def put(self, task_id):
128
129         try:
130             uuid.UUID(task_id)
131         except ValueError:
132             return result_handler(consts.API_ERROR, 'invalid task id')
133
134         task_handler = V2TaskHandler()
135         try:
136             task_handler.get_by_uuid(task_id)
137         except ValueError:
138             return result_handler(consts.API_ERROR, 'no such task id')
139
140         return self._dispatch_post(task_id=task_id)
141
142     def add_environment(self, args):
143
144         task_id = args['task_id']
145         try:
146             environment_id = args['environment_id']
147         except KeyError:
148             return result_handler(consts.API_ERROR, 'environment_id must be provided')
149
150         try:
151             uuid.UUID(environment_id)
152         except ValueError:
153             return result_handler(consts.API_ERROR, 'invalid environment id')
154
155         environment_handler = V2EnvironmentHandler()
156         try:
157             environment_handler.get_by_uuid(environment_id)
158         except ValueError:
159             return result_handler(consts.API_ERROR, 'no such environment id')
160
161         LOG.info('update environment_id in task')
162         task_handler = V2TaskHandler()
163         task_handler.update_attr(task_id, {'environment_id': environment_id})
164
165         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
166
167     def add_case(self, args):
168         task_id = args['task_id']
169         try:
170             name = args['case_name']
171         except KeyError:
172             return result_handler(consts.API_ERROR, 'case_name must be provided')
173
174         try:
175             content = args['case_content']
176         except KeyError:
177             return result_handler(consts.API_ERROR, 'case_content must be provided')
178
179         LOG.info('update case info in task')
180         task_handler = V2TaskHandler()
181         task_update_data = {
182             'case_name': name,
183             'content': content,
184             'suite': False
185         }
186         task_handler.update_attr(task_id, task_update_data)
187
188         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
189
190     def add_suite(self, args):
191         task_id = args['task_id']
192         try:
193             name = args['suite_name']
194         except KeyError:
195             return result_handler(consts.API_ERROR, 'suite_name must be provided')
196
197         try:
198             content = args['suite_content']
199         except KeyError:
200             return result_handler(consts.API_ERROR, 'suite_content must be provided')
201
202         LOG.info('update suite info in task')
203         task_handler = V2TaskHandler()
204         task_update_data = {
205             'case_name': name,
206             'content': content,
207             'suite': True
208         }
209         task_handler.update_attr(task_id, task_update_data)
210
211         return result_handler(consts.API_SUCCESS, {'uuid': task_id})
212
213     def run(self, args):
214         try:
215             task_id = args['task_id']
216         except KeyError:
217             return result_handler(consts.API_ERROR, 'task_id must be provided')
218
219         try:
220             uuid.UUID(task_id)
221         except ValueError:
222             return result_handler(consts.API_ERROR, 'invalid task id')
223
224         task_handler = V2TaskHandler()
225         try:
226             task = task_handler.get_by_uuid(task_id)
227         except ValueError:
228             return result_handler(consts.API_ERROR, 'no such task id')
229
230         if not task.environment_id:
231             return result_handler(consts.API_ERROR, 'environment not set')
232
233         if not task.case_name or not task.content:
234             return result_handler(consts.API_ERROR, 'case not set')
235
236         if task.status == 0:
237             return result_handler(consts.API_ERROR, 'task is already running')
238
239         with open('/tmp/{}.yaml'.format(task.case_name), 'w') as f:
240             f.write(task.content)
241
242         data = {
243             'inputfile': ['/tmp/{}.yaml'.format(task.case_name)],
244             'task_id': task_id
245         }
246         if task.suite:
247             data.update({'suite': True})
248
249         LOG.info('start task thread')
250         param = Param(data)
251         task_thread = TaskThread(Task().start, param, task_handler)
252         task_thread.start()
253
254         return result_handler(consts.API_SUCCESS, {'uuid': task_id})