blob: f5f0541cd69c2d7764749d7919b800aa57a691e4 [file] [log] [blame]
Michael Davis43366db2017-05-15 18:12:35 -05001/**
2 * Controller for firmware
3 *
4 * @module app/configuration
5 * @exports firmwareController
6 * @name firmwareController
Michael Davis43366db2017-05-15 18:12:35 -05007 */
8
9window.angular && (function (angular) {
10 'use strict';
11
12 angular
13 .module('app.configuration')
14 .controller('firmwareController', [
15 '$scope',
16 '$window',
17 'APIUtils',
18 'dataService',
19 '$location',
20 '$anchorScroll',
Iftekharul Islam1acb4122017-11-02 13:20:32 -050021 'Constants',
Gunnar Mills033025f2018-03-06 14:49:40 -060022 '$interval',
23 '$q',
Gunnar Mills90f8e692018-04-03 14:33:52 -050024 '$timeout',
25 function ($scope, $window, APIUtils, dataService, $location, $anchorScroll, Constants, $interval, $q, $timeout) {
Michael Davis43366db2017-05-15 18:12:35 -050026 $scope.dataService = dataService;
27
Michael Davis43366db2017-05-15 18:12:35 -050028 //Scroll to target anchor
29 $scope.gotoAnchor = function () {
30 $location.hash('upload');
31 $anchorScroll();
32 };
Iftekharul Islamc0161392017-06-14 15:46:15 -050033
34 $scope.firmwares = [];
35 $scope.bmcActiveVersion = "";
36 $scope.hostActiveVersion = "";
37 $scope.display_error = false;
Gunnar Millse7f83972018-03-21 11:03:35 -050038 $scope.activate_confirm = false;
Iftekharul Islamc0161392017-06-14 15:46:15 -050039 $scope.delete_image_id = "";
Gunnar Mills607a1202018-03-01 16:26:50 -060040 $scope.delete_image_version = "";
Iftekharul Islamc0161392017-06-14 15:46:15 -050041 $scope.activate_image_id = "";
Gunnar Millse7f83972018-03-21 11:03:35 -050042 $scope.activate_image_version = "";
Gunnar Millsee6efd82018-03-21 15:31:56 -050043 $scope.activate_image_type = "";
Iftekharul Islam1acb4122017-11-02 13:20:32 -050044 $scope.priority_image_id = "";
Gunnar Mills6473a412018-03-01 16:19:37 -060045 $scope.priority_image_version = "";
Iftekharul Islam1acb4122017-11-02 13:20:32 -050046 $scope.priority_from = -1;
47 $scope.priority_to = -1;
48 $scope.confirm_priority = false;
Iftekharul Islamc0161392017-06-14 15:46:15 -050049 $scope.file_empty = true;
50 $scope.uploading = false;
CamVan Nguyenf97adb92018-04-27 13:33:04 -050051 $scope.upload_success = false;
Gunnar Mills6d9ef5a2018-03-26 15:34:31 -050052 $scope.activate = { reboot: true };
Gunnar Mills6d7b4a82018-04-02 15:25:36 -050053 $scope.download_error_msg = "";
CamVan Nguyen58301ec2018-04-20 21:33:01 -050054 $scope.download_success = false;
Iftekharul Islamc0161392017-06-14 15:46:15 -050055
Gunnar Mills033025f2018-03-06 14:49:40 -060056 var pollActivationTimer = undefined;
CamVan Nguyen58301ec2018-04-20 21:33:01 -050057 var pollDownloadTimer = undefined;
Gunnar Mills033025f2018-03-06 14:49:40 -060058
Iftekharul Islamc0161392017-06-14 15:46:15 -050059 $scope.error = {
60 modal_title: "",
61 title: "",
62 desc: "",
63 type: "warning"
64 };
65
Gunnar Millsee6efd82018-03-21 15:31:56 -050066 $scope.activateImage = function(imageId, imageVersion, imageType){
Iftekharul Islamc0161392017-06-14 15:46:15 -050067 $scope.activate_image_id = imageId;
Gunnar Millse7f83972018-03-21 11:03:35 -050068 $scope.activate_image_version = imageVersion;
Gunnar Millsee6efd82018-03-21 15:31:56 -050069 $scope.activate_image_type = imageType;
Gunnar Millse7f83972018-03-21 11:03:35 -050070 $scope.activate_confirm = true;
Iftekharul Islamc0161392017-06-14 15:46:15 -050071 }
72
73 $scope.displayError = function(data){
74 $scope.error = data;
75 $scope.display_error = true;
76 }
77
Gunnar Mills033025f2018-03-06 14:49:40 -060078 function waitForActive(imageId){
79 var deferred = $q.defer();
80 var startTime = new Date();
81 pollActivationTimer = $interval(function(){
82 APIUtils.getActivation(imageId).then(function(state){
83 //@TODO: display an error message if image "Failed"
84 if(((/\.Active$/).test(state.data)) || ((/\.Failed$/).test(state.data))){
85 $interval.cancel(pollActivationTimer);
86 pollActivationTimer = undefined;
87 deferred.resolve(state);
88 }
89 }, function(error){
90 $interval.cancel(pollActivationTimer);
91 pollActivationTimer = undefined;
92 console.log(error);
93 deferred.reject(error);
Iftekharul Islam2a489552017-11-02 13:23:08 -050094 });
Gunnar Mills033025f2018-03-06 14:49:40 -060095 var now = new Date();
96 if((now.getTime() - startTime.getTime()) >= Constants.TIMEOUT.ACTIVATION){
97 $interval.cancel(pollActivationTimer);
98 pollActivationTimer = undefined;
99 console.log("Time out activating image, " + imageId);
100 deferred.reject("Time out. Image did not activate in allotted time.");
101 }
102 }, Constants.POLL_INTERVALS.ACTIVATION);
103 return deferred.promise;
104 }
105
106 $scope.activateConfirmed = function(){
107 APIUtils.activateImage($scope.activate_image_id).then(function(state){
108 $scope.loadFirmwares();
109 return state;
110 }, function(error){
111 $scope.displayError({
112 modal_title: 'Error during activation call',
113 title: 'Error during activation call',
114 desc: JSON.stringify(error.data),
115 type: 'Error'
116 });
117 }).then(function(activationState){
118 waitForActive($scope.activate_image_id).then(function(state){
119 $scope.loadFirmwares();
120 }, function(error){
121 $scope.displayError({
122 modal_title: 'Error during image activation',
123 title: 'Error during image activation',
124 desc: JSON.stringify(error.data),
125 type: 'Error'
126 });
Gunnar Mills6d9ef5a2018-03-26 15:34:31 -0500127 }).then(function(state){
Andrew Geisslera7bd3372018-05-16 16:39:41 -0500128 // Only look at reboot if it's a BMC image
129 if($scope.activate.reboot && ($scope.activate_image_type == 'BMC')){
Gunnar Mills90f8e692018-04-03 14:33:52 -0500130 // Despite the new image being active, issue,
131 // https://github.com/openbmc/openbmc/issues/2764, can cause a
132 // system to brick, if the system reboots before the service to set
133 // the U-Boot variables is complete. Wait 10 seconds before rebooting
134 // to ensure this service is complete. This issue is fixed in newer images, but
135 // the user may be updating from an older image that does not that have this fix.
136 // TODO: remove this timeout after sufficient time has passed.
137 $timeout(function() {
138 APIUtils.bmcReboot(function(response){}, function(error){
139 $scope.displayError({
140 modal_title: 'Error during BMC reboot',
141 title: 'Error during BMC reboot',
142 desc: JSON.stringify(error.data),
143 type: 'Error'
144 });
Gunnar Mills6d9ef5a2018-03-26 15:34:31 -0500145 });
Gunnar Mills90f8e692018-04-03 14:33:52 -0500146 }, 10000);
Gunnar Mills6d9ef5a2018-03-26 15:34:31 -0500147 }
Gunnar Mills033025f2018-03-06 14:49:40 -0600148 });
149 });
150 $scope.activate_confirm = false;
Iftekharul Islamc0161392017-06-14 15:46:15 -0500151 }
152
Iftekharul Islamc0161392017-06-14 15:46:15 -0500153 $scope.upload = function(){
Gunnar Mills87c3db62018-04-13 16:14:41 -0500154 if($scope.file) {
155 $scope.uploading = true;
CamVan Nguyenf97adb92018-04-27 13:33:04 -0500156 $scope.upload_success = false;
Gunnar Mills87c3db62018-04-13 16:14:41 -0500157 APIUtils.uploadImage($scope.file).then(function(response){
CamVan Nguyenf97adb92018-04-27 13:33:04 -0500158 $scope.file = "";
Gunnar Mills87c3db62018-04-13 16:14:41 -0500159 $scope.uploading = false;
CamVan Nguyenf97adb92018-04-27 13:33:04 -0500160 $scope.upload_success = true;
Gunnar Mills87c3db62018-04-13 16:14:41 -0500161 $scope.loadFirmwares();
162 }, function(error){
163 $scope.uploading = false;
CamVan Nguyenf97adb92018-04-27 13:33:04 -0500164 console.log(error);
Gunnar Mills87c3db62018-04-13 16:14:41 -0500165 $scope.displayError({
166 modal_title: 'Error during image upload',
167 title: 'Error during image upload',
CamVan Nguyenf97adb92018-04-27 13:33:04 -0500168 desc: error,
169 type: 'Error'
Gunnar Mills87c3db62018-04-13 16:14:41 -0500170 });
171 });
172 }
Iftekharul Islamc0161392017-06-14 15:46:15 -0500173 }
Iftekharul Islamc0161392017-06-14 15:46:15 -0500174
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500175 //TODO: openbmc/openbmc#1691 Add support to return
176 //the id of the newly created image, downloaded via
177 //tftp. Polling the number of software objects is a
178 //near term solution.
179 function waitForDownload(){
180 var deferred = $q.defer();
181 var startTime = new Date();
182 pollDownloadTimer = $interval(function(){
183 var now = new Date();
184 if((now.getTime() - startTime.getTime()) >= Constants.TIMEOUT.DOWNLOAD_IMAGE){
185 $interval.cancel(pollDownloadTimer);
186 pollDownloadTimer = undefined;
187 deferred.reject(new Error(Constants.MESSAGES.POLL.DOWNLOAD_IMAGE_TIMEOUT));
188 }
189
190 APIUtils.getFirmwares().then(function(response){
191 if(response.data.length === $scope.firmwares.length + 1){
192 $interval.cancel(pollDownloadTimer);
193 pollDownloadTimer = undefined;
194 deferred.resolve(response.data);
195 }
196 }, function(error){
197 $interval.cancel(pollDownloadTimer);
198 pollDownloadTimer = undefined;
199 deferred.reject(error);
200 });
201 }, Constants.POLL_INTERVALS.DOWNLOAD_IMAGE);
202
203 return deferred.promise;
204 }
205
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500206 $scope.download = function(){
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500207 $scope.download_success = false;
Gunnar Mills6d7b4a82018-04-02 15:25:36 -0500208 $scope.download_error_msg = "";
209 if(!$scope.download_host || !$scope.download_filename){
Gunnar Mills36379b92018-04-02 16:53:53 -0500210 $scope.download_error_msg = "Field is required!";
211 return false;
Gunnar Mills6d7b4a82018-04-02 15:25:36 -0500212 }
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500213
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500214 $scope.downloading = true;
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500215 APIUtils.getFirmwares().then(function(response){
216 $scope.firmwares = response.data;
217 }).then(function(){
218 return APIUtils.downloadImage($scope.download_host,
219 $scope.download_filename).then(function(downloadStatus){
220 return downloadStatus;
221 });
222 }).then(function(downloadStatus){
223 return waitForDownload();
224 }).then(function(newFirmwareList){
225 $scope.download_host = "";
226 $scope.download_filename = "";
227 $scope.downloading = false;
228 $scope.download_success = true;
229 $scope.loadFirmwares();
Gunnar Mills36379b92018-04-02 16:53:53 -0500230 }, function(error){
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500231 console.log(error);
232 $scope.displayError({
233 modal_title: 'Error during downloading Image',
234 title: 'Error during downloading Image',
235 desc: error,
236 type: 'Error'
237 });
238 $scope.downloading = false;
239 });
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500240 }
241
Gunnar Mills6473a412018-03-01 16:19:37 -0600242 $scope.changePriority = function(imageId, imageVersion, from, to){
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500243 $scope.priority_image_id = imageId;
Gunnar Mills6473a412018-03-01 16:19:37 -0600244 $scope.priority_image_version = imageVersion;
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500245 $scope.priority_from = from;
246 $scope.priority_to = to;
Gunnar Millsf4d9bc42018-03-06 15:42:40 -0600247 $scope.confirm_priority = true;
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500248 }
249
250 $scope.confirmChangePriority = function(){
251 $scope.loading = true;
252 APIUtils.changePriority($scope.priority_image_id, $scope.priority_to).then(function(response){
253 $scope.loading = false;
254 if(response.status == 'error'){
255 $scope.displayError({
256 modal_title: response.data.description,
257 title: response.data.description,
258 desc: response.data.exception,
259 type: 'Error'
260 });
261 }else{
262 $scope.loadFirmwares();
263 }
264 });
265 $scope.confirm_priority = false;
266 }
Gunnar Mills607a1202018-03-01 16:26:50 -0600267 $scope.deleteImage = function(imageId, imageVersion){
Iftekharul Islamc0161392017-06-14 15:46:15 -0500268 $scope.delete_image_id = imageId;
Gunnar Mills607a1202018-03-01 16:26:50 -0600269 $scope.delete_image_version = imageVersion;
Iftekharul Islamc0161392017-06-14 15:46:15 -0500270 $scope.confirm_delete = true;
271 }
Iftekharul Islam2a489552017-11-02 13:23:08 -0500272 $scope.confirmDeleteImage = function(){
273 $scope.loading = true;
274 APIUtils.deleteImage($scope.delete_image_id).then(function(response){
275 $scope.loading = false;
276 if(response.status == 'error'){
277 $scope.displayError({
278 modal_title: response.data.description,
279 title: response.data.description,
280 desc: response.data.exception,
281 type: 'Error'
282 });
283 }else{
284 $scope.loadFirmwares();
285 }
286 });
Iftekharul Islamc0161392017-06-14 15:46:15 -0500287 $scope.confirm_delete = false;
288 }
Iftekharul Islamc0161392017-06-14 15:46:15 -0500289 $scope.fileNameChanged = function(){
290 $scope.file_empty = false;
291 }
292
Iftekharul Islamc0161392017-06-14 15:46:15 -0500293 $scope.filters = {
294 bmc: {
295 imageType: 'BMC'
296 },
297 host: {
298 imageType: 'Host'
299 }
300 };
301
302 $scope.loadFirmwares = function(){
Michael Davisdf3bd122017-08-10 11:03:42 -0500303 APIUtils.getFirmwares().then(function(result){
304 $scope.firmwares = result.data;
305 $scope.bmcActiveVersion = result.bmcActiveVersion;
306 $scope.hostActiveVersion = result.hostActiveVersion;
Iftekharul Islamc0161392017-06-14 15:46:15 -0500307 });
308 }
309
310 $scope.loadFirmwares();
Michael Davis43366db2017-05-15 18:12:35 -0500311 }
312 ]
313 );
314
315})(angular);