blob: cf838eced747826c1f7e957eaff1c2ac4d3dfdc4 [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
Andrew Geisslerba5e3f32018-05-24 10:58:00 -07009window.angular && (function(angular) {
10 'use strict';
Michael Davis43366db2017-05-15 18:12:35 -050011
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070012 angular
13 .module('app.configuration')
14 .controller('firmwareController', [
15 '$scope',
16 '$window',
17 'APIUtils',
18 'dataService',
19 '$location',
20 '$anchorScroll',
21 'Constants',
22 '$interval',
23 '$q',
24 '$timeout',
25 function($scope, $window, APIUtils, dataService, $location, $anchorScroll, Constants, $interval, $q, $timeout) {
26 $scope.dataService = dataService;
Michael Davis43366db2017-05-15 18:12:35 -050027
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070028 //Scroll to target anchor
29 $scope.gotoAnchor = function() {
30 $location.hash('upload');
31 $anchorScroll();
32 };
Iftekharul Islamc0161392017-06-14 15:46:15 -050033
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070034 $scope.firmwares = [];
35 $scope.bmcActiveVersion = '';
36 $scope.hostActiveVersion = '';
37 $scope.display_error = false;
38 $scope.activate_confirm = false;
39 $scope.delete_image_id = '';
40 $scope.delete_image_version = '';
41 $scope.activate_image_id = '';
42 $scope.activate_image_version = '';
43 $scope.activate_image_type = '';
44 $scope.priority_image_id = '';
45 $scope.priority_image_version = '';
46 $scope.priority_from = -1;
47 $scope.priority_to = -1;
48 $scope.confirm_priority = false;
49 $scope.file_empty = true;
50 $scope.uploading = false;
51 $scope.upload_success = false;
52 $scope.activate = {
53 reboot: true
54 };
55 $scope.download_error_msg = '';
56 $scope.download_success = false;
Iftekharul Islamc0161392017-06-14 15:46:15 -050057
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070058 var pollActivationTimer = undefined;
59 var pollDownloadTimer = undefined;
Gunnar Mills033025f2018-03-06 14:49:40 -060060
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070061 $scope.error = {
62 modal_title: '',
63 title: '',
64 desc: '',
65 type: 'warning'
66 };
Iftekharul Islamc0161392017-06-14 15:46:15 -050067
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070068 $scope.activateImage = function(imageId, imageVersion, imageType) {
69 $scope.activate_image_id = imageId;
70 $scope.activate_image_version = imageVersion;
71 $scope.activate_image_type = imageType;
72 $scope.activate_confirm = true;
73 };
Iftekharul Islamc0161392017-06-14 15:46:15 -050074
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070075 $scope.displayError = function(data) {
76 $scope.error = data;
77 $scope.display_error = true;
78 };
Iftekharul Islamc0161392017-06-14 15:46:15 -050079
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070080 function waitForActive(imageId) {
81 var deferred = $q.defer();
82 var startTime = new Date();
83 pollActivationTimer = $interval(function() {
84 APIUtils.getActivation(imageId).then(function(state) {
85 //@TODO: display an error message if image "Failed"
86 if (((/\.Active$/).test(state.data)) || ((/\.Failed$/).test(state.data))) {
87 $interval.cancel(pollActivationTimer);
88 pollActivationTimer = undefined;
89 deferred.resolve(state);
90 }
91 }, function(error) {
92 $interval.cancel(pollActivationTimer);
93 pollActivationTimer = undefined;
94 console.log(error);
95 deferred.reject(error);
96 });
97 var now = new Date();
98 if ((now.getTime() - startTime.getTime()) >= Constants.TIMEOUT.ACTIVATION) {
99 $interval.cancel(pollActivationTimer);
100 pollActivationTimer = undefined;
101 console.log('Time out activating image, ' + imageId);
102 deferred.reject('Time out. Image did not activate in allotted time.');
103 }
104 }, Constants.POLL_INTERVALS.ACTIVATION);
105 return deferred.promise;
106 }
Gunnar Mills033025f2018-03-06 14:49:40 -0600107
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700108 $scope.activateConfirmed = function() {
109 APIUtils.activateImage($scope.activate_image_id).then(function(state) {
110 $scope.loadFirmwares();
111 return state;
112 }, function(error) {
113 $scope.displayError({
114 modal_title: 'Error during activation call',
115 title: 'Error during activation call',
116 desc: JSON.stringify(error.data),
117 type: 'Error'
118 });
119 }).then(function(activationState) {
120 waitForActive($scope.activate_image_id).then(function(state) {
121 $scope.loadFirmwares();
122 }, function(error) {
123 $scope.displayError({
124 modal_title: 'Error during image activation',
125 title: 'Error during image activation',
126 desc: JSON.stringify(error.data),
127 type: 'Error'
128 });
129 }).then(function(state) {
130 // Only look at reboot if it's a BMC image
131 if ($scope.activate.reboot && ($scope.activate_image_type == 'BMC')) {
132 // Despite the new image being active, issue,
133 // https://github.com/openbmc/openbmc/issues/2764, can cause a
134 // system to brick, if the system reboots before the service to set
135 // the U-Boot variables is complete. Wait 10 seconds before rebooting
136 // to ensure this service is complete. This issue is fixed in newer images, but
137 // the user may be updating from an older image that does not that have this fix.
138 // TODO: remove this timeout after sufficient time has passed.
139 $timeout(function() {
140 APIUtils.bmcReboot(function(response) {}, function(error) {
141 $scope.displayError({
142 modal_title: 'Error during BMC reboot',
143 title: 'Error during BMC reboot',
144 desc: JSON.stringify(error.data),
145 type: 'Error'
146 });
147 });
148 }, 10000);
149 }
150 });
151 });
152 $scope.activate_confirm = false;
153 };
Iftekharul Islamc0161392017-06-14 15:46:15 -0500154
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700155 $scope.upload = function() {
156 if ($scope.file) {
157 $scope.uploading = true;
158 $scope.upload_success = false;
159 APIUtils.uploadImage($scope.file).then(function(response) {
160 $scope.file = '';
161 $scope.uploading = false;
162 $scope.upload_success = true;
163 $scope.loadFirmwares();
164 }, function(error) {
165 $scope.uploading = false;
166 console.log(error);
167 $scope.displayError({
168 modal_title: 'Error during image upload',
169 title: 'Error during image upload',
170 desc: error,
171 type: 'Error'
172 });
173 });
174 }
175 };
Iftekharul Islamc0161392017-06-14 15:46:15 -0500176
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700177 //TODO: openbmc/openbmc#1691 Add support to return
178 //the id of the newly created image, downloaded via
179 //tftp. Polling the number of software objects is a
180 //near term solution.
181 function waitForDownload() {
182 var deferred = $q.defer();
183 var startTime = new Date();
184 pollDownloadTimer = $interval(function() {
185 var now = new Date();
186 if ((now.getTime() - startTime.getTime()) >= Constants.TIMEOUT.DOWNLOAD_IMAGE) {
187 $interval.cancel(pollDownloadTimer);
188 pollDownloadTimer = undefined;
189 deferred.reject(new Error(Constants.MESSAGES.POLL.DOWNLOAD_IMAGE_TIMEOUT));
190 }
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500191
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700192 APIUtils.getFirmwares().then(function(response) {
193 if (response.data.length === $scope.firmwares.length + 1) {
194 $interval.cancel(pollDownloadTimer);
195 pollDownloadTimer = undefined;
196 deferred.resolve(response.data);
197 }
198 }, function(error) {
199 $interval.cancel(pollDownloadTimer);
200 pollDownloadTimer = undefined;
201 deferred.reject(error);
202 });
203 }, Constants.POLL_INTERVALS.DOWNLOAD_IMAGE);
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500204
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700205 return deferred.promise;
206 }
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500207
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700208 $scope.download = function() {
209 $scope.download_success = false;
210 $scope.download_error_msg = '';
211 if (!$scope.download_host || !$scope.download_filename) {
212 $scope.download_error_msg = 'Field is required!';
213 return false;
214 }
CamVan Nguyen58301ec2018-04-20 21:33:01 -0500215
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700216 $scope.downloading = true;
217 APIUtils.getFirmwares().then(function(response) {
218 $scope.firmwares = response.data;
219 }).then(function() {
220 return APIUtils.downloadImage($scope.download_host,
221 $scope.download_filename).then(function(downloadStatus) {
222 return downloadStatus;
223 });
224 }).then(function(downloadStatus) {
225 return waitForDownload();
226 }).then(function(newFirmwareList) {
227 $scope.download_host = '';
228 $scope.download_filename = '';
229 $scope.downloading = false;
230 $scope.download_success = true;
231 $scope.loadFirmwares();
232 }, function(error) {
233 console.log(error);
234 $scope.displayError({
235 modal_title: 'Error during downloading Image',
236 title: 'Error during downloading Image',
237 desc: error,
238 type: 'Error'
239 });
240 $scope.downloading = false;
241 });
242 };
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500243
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700244 $scope.changePriority = function(imageId, imageVersion, from, to) {
245 $scope.priority_image_id = imageId;
246 $scope.priority_image_version = imageVersion;
247 $scope.priority_from = from;
248 $scope.priority_to = to;
249 $scope.confirm_priority = true;
250 };
Iftekharul Islam1acb4122017-11-02 13:20:32 -0500251
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700252 $scope.confirmChangePriority = function() {
253 $scope.loading = true;
254 APIUtils.changePriority($scope.priority_image_id, $scope.priority_to).then(function(response) {
255 $scope.loading = false;
256 if (response.status == 'error') {
257 $scope.displayError({
258 modal_title: response.data.description,
259 title: response.data.description,
260 desc: response.data.exception,
261 type: 'Error'
262 });
263 }
264 else {
265 $scope.loadFirmwares();
266 }
267 });
268 $scope.confirm_priority = false;
269 };
270 $scope.deleteImage = function(imageId, imageVersion) {
271 $scope.delete_image_id = imageId;
272 $scope.delete_image_version = imageVersion;
273 $scope.confirm_delete = true;
274 };
275 $scope.confirmDeleteImage = function() {
276 $scope.loading = true;
277 APIUtils.deleteImage($scope.delete_image_id).then(function(response) {
278 $scope.loading = false;
279 if (response.status == 'error') {
280 $scope.displayError({
281 modal_title: response.data.description,
282 title: response.data.description,
283 desc: response.data.exception,
284 type: 'Error'
285 });
286 }
287 else {
288 $scope.loadFirmwares();
289 }
290 });
291 $scope.confirm_delete = false;
292 };
293 $scope.fileNameChanged = function() {
294 $scope.file_empty = false;
295 };
Iftekharul Islamc0161392017-06-14 15:46:15 -0500296
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700297 $scope.filters = {
298 bmc: {
299 imageType: 'BMC'
300 },
301 host: {
302 imageType: 'Host'
303 }
304 };
Iftekharul Islamc0161392017-06-14 15:46:15 -0500305
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700306 $scope.loadFirmwares = function() {
307 APIUtils.getFirmwares().then(function(result) {
308 $scope.firmwares = result.data;
309 $scope.bmcActiveVersion = result.bmcActiveVersion;
310 $scope.hostActiveVersion = result.hostActiveVersion;
311 });
312 };
Iftekharul Islamc0161392017-06-14 15:46:15 -0500313
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700314 $scope.loadFirmwares();
315 }
316 ]);
Michael Davis43366db2017-05-15 18:12:35 -0500317
318})(angular);