diff options
author | Hiroyuki Eguchi <h-eguchi@az.jp.nec.com> | 2017-03-29 12:50:54 +0900 |
---|---|---|
committer | Hiroyuki Eguchi <h-eguchi@az.jp.nec.com> | 2017-03-29 12:50:58 +0900 |
commit | aa6fe37f231371cef4f0e7b2bbe6c1eb1b0ed799 (patch) | |
tree | 5ab108cbb4e1b71620dd88062abd520951fe3164 | |
parent | 312a5742ea54a2b174d054260fb48607d185b53b (diff) |
Add a recreate model action
Add a recreate model action
in model panel.
implements blueprint recreate-model
Change-Id: I1465a1bf170cd37bf98a7081a4277b4cb5f845d6
Notes
Notes (review):
Code-Review+2: Hiroyuki Eguchi <h-eguchi@az.jp.nec.com>
Workflow+1: Hiroyuki Eguchi <h-eguchi@az.jp.nec.com>
Verified+2: Jenkins
Submitted-by: Jenkins
Submitted-at: Wed, 29 Mar 2017 04:15:03 +0000
Reviewed-on: https://review.openstack.org/451164
Project: openstack/meteos-ui
Branch: refs/heads/master
7 files changed, 157 insertions, 1 deletions
diff --git a/meteos_ui/api/client.py b/meteos_ui/api/client.py index db84519..5a23017 100644 --- a/meteos_ui/api/client.py +++ b/meteos_ui/api/client.py | |||
@@ -154,6 +154,17 @@ def model_create(request, **kwargs): | |||
154 | return meteosclient(request).models.create(**args) | 154 | return meteosclient(request).models.create(**args) |
155 | 155 | ||
156 | 156 | ||
157 | def model_recreate(request, id, **kwargs): | ||
158 | args = {} | ||
159 | for (key, value) in kwargs.items(): | ||
160 | if key in MODEL_CREATE_ATTRS: | ||
161 | args[str(key)] = str(value) | ||
162 | else: | ||
163 | raise exceptions.BadRequest( | ||
164 | "Key must be in %s" % ",".join(MODEL_CREATE_ATTRS)) | ||
165 | return meteosclient(request).models.recreate(id, **args) | ||
166 | |||
167 | |||
157 | def model_delete(request, id): | 168 | def model_delete(request, id): |
158 | return meteosclient(request).models.delete(id) | 169 | return meteosclient(request).models.delete(id) |
159 | 170 | ||
diff --git a/meteos_ui/api/rest_api.py b/meteos_ui/api/rest_api.py index 0dbcdbf..977a4ef 100644 --- a/meteos_ui/api/rest_api.py +++ b/meteos_ui/api/rest_api.py | |||
@@ -200,6 +200,11 @@ class ModelActions(generic.View): | |||
200 | return client.model_load(request, id) | 200 | return client.model_load(request, id) |
201 | elif action == 'unload': | 201 | elif action == 'unload': |
202 | return client.model_unload(request, id) | 202 | return client.model_unload(request, id) |
203 | elif action == 'recreate': | ||
204 | new_model = client.model_recreate(request, id, **request.DATA) | ||
205 | return rest_utils.CreatedResponse( | ||
206 | '/api/meteos/model/%s' % new_model.id, | ||
207 | new_model.to_dict()) | ||
203 | 208 | ||
204 | 209 | ||
205 | @urls.register | 210 | @urls.register |
diff --git a/meteos_ui/static/dashboard/machine_learning/meteos.service.js b/meteos_ui/static/dashboard/machine_learning/meteos.service.js index f955c67..29bb5ae 100644 --- a/meteos_ui/static/dashboard/machine_learning/meteos.service.js +++ b/meteos_ui/static/dashboard/machine_learning/meteos.service.js | |||
@@ -42,6 +42,7 @@ | |||
42 | deleteDataset: deleteDataset, | 42 | deleteDataset: deleteDataset, |
43 | deleteDatasets: deleteDatasets, | 43 | deleteDatasets: deleteDatasets, |
44 | createModel: createModel, | 44 | createModel: createModel, |
45 | recreateModel: recreateModel, | ||
45 | getModel: getModel, | 46 | getModel: getModel, |
46 | getModels: getModels, | 47 | getModels: getModels, |
47 | deleteModel: deleteModel, | 48 | deleteModel: deleteModel, |
@@ -211,6 +212,13 @@ | |||
211 | }); | 212 | }); |
212 | } | 213 | } |
213 | 214 | ||
215 | function recreateModel(id, params) { | ||
216 | return apiService.post('/api/meteos/models/' + id + '/recreate', params) | ||
217 | .error(function() { | ||
218 | toastService.add('error', gettext('Unable to recreate Model')); | ||
219 | }); | ||
220 | } | ||
221 | |||
214 | function getModel(id) { | 222 | function getModel(id) { |
215 | return apiService.get('/api/meteos/models/' + id) | 223 | return apiService.get('/api/meteos/models/' + id) |
216 | .success(function(data, status, headers, config) { | 224 | .success(function(data, status, headers, config) { |
diff --git a/meteos_ui/static/dashboard/machine_learning/models/actions.module.js b/meteos_ui/static/dashboard/machine_learning/models/actions.module.js index 43e6187..30535aa 100644 --- a/meteos_ui/static/dashboard/machine_learning/models/actions.module.js +++ b/meteos_ui/static/dashboard/machine_learning/models/actions.module.js | |||
@@ -30,6 +30,7 @@ | |||
30 | 'horizon.framework.util.i18n.gettext', | 30 | 'horizon.framework.util.i18n.gettext', |
31 | 'horizon.dashboard.machine_learning.models.create.service', | 31 | 'horizon.dashboard.machine_learning.models.create.service', |
32 | 'horizon.dashboard.machine_learning.models.delete.service', | 32 | 'horizon.dashboard.machine_learning.models.delete.service', |
33 | 'horizon.dashboard.machine_learning.models.recreate.service', | ||
33 | 'horizon.dashboard.machine_learning.models.load.service', | 34 | 'horizon.dashboard.machine_learning.models.load.service', |
34 | 'horizon.dashboard.machine_learning.models.unload.service', | 35 | 'horizon.dashboard.machine_learning.models.unload.service', |
35 | 'horizon.dashboard.machine_learning.models.resourceType', | 36 | 'horizon.dashboard.machine_learning.models.resourceType', |
@@ -40,6 +41,7 @@ | |||
40 | gettext, | 41 | gettext, |
41 | createModelService, | 42 | createModelService, |
42 | deleteModelService, | 43 | deleteModelService, |
44 | recreateModelService, | ||
43 | loadModelService, | 45 | loadModelService, |
44 | unloadModelService, | 46 | unloadModelService, |
45 | resourceType) | 47 | resourceType) |
@@ -68,6 +70,13 @@ | |||
68 | 70 | ||
69 | modelsResourceType.itemActions | 71 | modelsResourceType.itemActions |
70 | .append({ | 72 | .append({ |
73 | id: 'recreateModelAction', | ||
74 | service: recreateModelService, | ||
75 | template: { | ||
76 | text: gettext('Recreate Model') | ||
77 | } | ||
78 | }) | ||
79 | .append({ | ||
71 | id: 'loadModelAction', | 80 | id: 'loadModelAction', |
72 | service: loadModelService, | 81 | service: loadModelService, |
73 | template: { | 82 | template: { |
diff --git a/meteos_ui/static/dashboard/machine_learning/models/create/info/info.html b/meteos_ui/static/dashboard/machine_learning/models/create/info/info.html index b22f6a5..d2a26c1 100644 --- a/meteos_ui/static/dashboard/machine_learning/models/create/info/info.html +++ b/meteos_ui/static/dashboard/machine_learning/models/create/info/info.html | |||
@@ -25,6 +25,7 @@ | |||
25 | <select class="form-control" | 25 | <select class="form-control" |
26 | ng-model="model.newModelSpec.experiment_id" | 26 | ng-model="model.newModelSpec.experiment_id" |
27 | ng-required="true" | 27 | ng-required="true" |
28 | ng-disabled="model.id" | ||
28 | ng-options="experiment.id as experiment.name + ':' + experiment.id for experiment in ctrl.experiments"> | 29 | ng-options="experiment.id as experiment.name + ':' + experiment.id for experiment in ctrl.experiments"> |
29 | </select> | 30 | </select> |
30 | </div> | 31 | </div> |
diff --git a/meteos_ui/static/dashboard/machine_learning/models/create/model-model.js b/meteos_ui/static/dashboard/machine_learning/models/create/model-model.js index 0fbda3e..1642534 100644 --- a/meteos_ui/static/dashboard/machine_learning/models/create/model-model.js +++ b/meteos_ui/static/dashboard/machine_learning/models/create/model-model.js | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | function modelModel(meteos) { | 26 | function modelModel(meteos) { |
27 | var model = { | 27 | var model = { |
28 | id: null, | ||
28 | newModelSpec: {}, | 29 | newModelSpec: {}, |
29 | newCommonDataset: {}, | 30 | newCommonDataset: {}, |
30 | newParamsSpec: {}, | 31 | newParamsSpec: {}, |
@@ -86,6 +87,7 @@ | |||
86 | } | 87 | } |
87 | 88 | ||
88 | function createModel() { | 89 | function createModel() { |
90 | var modelId = model.id; | ||
89 | var finalSpec = angular.copy(model.newModelSpec); | 91 | var finalSpec = angular.copy(model.newModelSpec); |
90 | var commonDataset = angular.copy(model.newCommonDataset); | 92 | var commonDataset = angular.copy(model.newCommonDataset); |
91 | var finalParams = angular.copy(model.newParamsSpec); | 93 | var finalParams = angular.copy(model.newParamsSpec); |
@@ -109,7 +111,12 @@ | |||
109 | finalSpec.swift_username = commonDataset.swift_username; | 111 | finalSpec.swift_username = commonDataset.swift_username; |
110 | finalSpec.swift_password = commonDataset.swift_password; | 112 | finalSpec.swift_password = commonDataset.swift_password; |
111 | 113 | ||
112 | return meteos.createModel(finalSpec); | 114 | if(modelId){ |
115 | delete finalSpec['experiment_id']; | ||
116 | return meteos.recreateModel(modelId, finalSpec); | ||
117 | }else{ | ||
118 | return meteos.createModel(finalSpec); | ||
119 | } | ||
113 | } | 120 | } |
114 | 121 | ||
115 | 122 | ||
diff --git a/meteos_ui/static/dashboard/machine_learning/models/operations/recreate.service.js b/meteos_ui/static/dashboard/machine_learning/models/operations/recreate.service.js new file mode 100644 index 0000000..1fbef07 --- /dev/null +++ b/meteos_ui/static/dashboard/machine_learning/models/operations/recreate.service.js | |||
@@ -0,0 +1,115 @@ | |||
1 | /** | ||
2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
3 | * not use this file except in compliance with the License. You may obtain | ||
4 | * a copy of the License at | ||
5 | * | ||
6 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
7 | * | ||
8 | * Unless required by applicable law or agreed to in writing, software | ||
9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
11 | * License for the specific language governing permissions and limitations | ||
12 | * under the License. | ||
13 | */ | ||
14 | |||
15 | (function() { | ||
16 | 'use strict'; | ||
17 | |||
18 | /** | ||
19 | * @ngdoc overview | ||
20 | * @name horizon.dashboard.machine_learning.models.create.service | ||
21 | * @description Service for the model create modal | ||
22 | */ | ||
23 | angular | ||
24 | .module('horizon.dashboard.machine_learning.models') | ||
25 | .factory('horizon.dashboard.machine_learning.models.recreate.service', recreateService); | ||
26 | |||
27 | recreateService.$inject = [ | ||
28 | '$location', | ||
29 | 'horizon.app.core.openstack-service-api.policy', | ||
30 | 'horizon.framework.util.actions.action-result.service', | ||
31 | 'horizon.framework.util.i18n.gettext', | ||
32 | 'horizon.framework.util.q.extensions', | ||
33 | 'horizon.framework.widgets.modal.wizard-modal.service', | ||
34 | 'horizon.framework.widgets.toast.service', | ||
35 | 'horizon.dashboard.machine_learning.models.modelModel', | ||
36 | 'horizon.dashboard.machine_learning.models.events', | ||
37 | 'horizon.dashboard.machine_learning.models.resourceType', | ||
38 | 'horizon.dashboard.machine_learning.models.workflow' | ||
39 | ]; | ||
40 | |||
41 | function recreateService( | ||
42 | $location, policy, actionResult, gettext, $qExtensions, wizardModalService, toast, model, events, resourceType, createWorkflow | ||
43 | ) { | ||
44 | var scope; | ||
45 | var message = { | ||
46 | success: gettext('Model %s was successfully recreated.') | ||
47 | }; | ||
48 | |||
49 | var service = { | ||
50 | initAction: initAction, | ||
51 | perform: perform, | ||
52 | allowed: allowed | ||
53 | }; | ||
54 | |||
55 | return service; | ||
56 | |||
57 | ////////////// | ||
58 | |||
59 | function initAction() { | ||
60 | } | ||
61 | |||
62 | function perform(selected, newScope) { | ||
63 | scope = newScope; | ||
64 | scope.workflow = createWorkflow; | ||
65 | scope.model = model; | ||
66 | scope.model.init(); | ||
67 | scope.model.id = selected.id; | ||
68 | // for creation according to selected item | ||
69 | scope.selected = selected; | ||
70 | |||
71 | scope.model.newModelSpec.display_name = selected.name; | ||
72 | scope.model.newModelSpec.display_description = selected.description; | ||
73 | scope.model.newModelSpec.experiment_id = selected.experiment_id; | ||
74 | scope.model.newModelSpec.model_type = selected.type; | ||
75 | |||
76 | var s_url = selected.source_dataset_url.split('://'); | ||
77 | |||
78 | if (s_url[0] === 'swift'){ | ||
79 | scope.model.newCommonDataset.location = 'swift'; | ||
80 | scope.model.newCommonDataset.container_name = s_url[1].split('/')[0]; | ||
81 | scope.model.newCommonDataset.object_name = s_url[1].split('/')[1]; | ||
82 | }else{ | ||
83 | scope.model.newCommonDataset.location = 'internal'; | ||
84 | scope.model.newCommonDataset.dataset_uuid = s_url[1]; | ||
85 | } | ||
86 | |||
87 | return wizardModalService.modal({ | ||
88 | scope: scope, | ||
89 | workflow: createWorkflow, | ||
90 | submit: submit | ||
91 | }).result; | ||
92 | } | ||
93 | |||
94 | function allowed() { | ||
95 | return $qExtensions.booleanAsPromise(true); | ||
96 | //return policy.ifAllowed({ rules: [['model', 'add_model']] }); | ||
97 | } | ||
98 | |||
99 | function submit(){ | ||
100 | return model.createModel().then(success); | ||
101 | } | ||
102 | |||
103 | function success(response) { | ||
104 | response.data.id = response.data.id; | ||
105 | toast.add('success', interpolate(message.success, [response.data.id])); | ||
106 | var result = actionResult.getActionResult() | ||
107 | .created(resourceType, response.data.id); | ||
108 | if(result.result.failed.length == 0 && result.result.created.length > 0){ | ||
109 | $location.path('/project/machine_learning/models'); | ||
110 | }else{ | ||
111 | return result.result; | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | })(); | ||