blob: 5d2459d37b277ea698929d6a88ed3a4e21bb5650 [file] [log] [blame]
Iftekharul Islamcd789502017-04-19 14:37:55 -05001/**
2 * Controller for date-time
3 *
4 * @module app/configuration
5 * @exports dateTimeController
6 * @name dateTimeController
Iftekharul Islamcd789502017-04-19 14:37:55 -05007 */
8
Andrew Geisslerba5e3f32018-05-24 10:58:00 -07009window.angular && (function(angular) {
10 'use strict';
Iftekharul Islamcd789502017-04-19 14:37:55 -050011
Andrew Geisslerd27bb132018-05-24 11:07:27 -070012 angular.module('app.configuration').controller('dateTimeController', [
Gunnar Millsb7ea2792018-07-18 13:01:48 -050013 '$scope', '$window', 'APIUtils', '$route', '$q',
14 function($scope, $window, APIUtils, $route, $q) {
15 $scope.bmc = {};
Gunnar Millseab32132018-09-27 10:07:17 -050016 // Only used when the owner is "Split"
Gunnar Millsb7ea2792018-07-18 13:01:48 -050017 $scope.host = {};
18 $scope.ntp = {servers: []};
Gunnar Mills2f955bd2018-10-13 16:56:10 -050019 $scope.time = {mode: '', owner: ''};
20 // Possible time owners
21 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Time/Owner.interface.yaml#L13
22 $scope.timeOwners = ['BMC', 'Host', 'Both', 'Split'];
23 $scope.error = false;
24 $scope.success = false;
Gunnar Mills7de38662018-07-18 13:01:48 -050025 $scope.loading = true;
Gunnar Mills2f955bd2018-10-13 16:56:10 -050026 var timePath = '/xyz/openbmc_project/time/';
Gunnar Mills7de38662018-07-18 13:01:48 -050027
Gunnar Millsc74d4342018-07-18 14:52:02 -050028 var getTimePromise = APIUtils.getTime().then(
Gunnar Mills7de38662018-07-18 13:01:48 -050029 function(data) {
Gunnar Millsb7ea2792018-07-18 13:01:48 -050030 // The time is returned as Epoch microseconds convert to
31 // milliseconds.
Gunnar Mills2f955bd2018-10-13 16:56:10 -050032 if (data.data[timePath + 'bmc'] &&
33 data.data[timePath + 'bmc'].hasOwnProperty('Elapsed')) {
Gunnar Millsb7ea2792018-07-18 13:01:48 -050034 $scope.bmc.date =
Gunnar Mills2f955bd2018-10-13 16:56:10 -050035 new Date(data.data[timePath + 'bmc'].Elapsed / 1000);
Gunnar Millsb7ea2792018-07-18 13:01:48 -050036 // Don't care about milliseconds and don't want them displayed
37 $scope.bmc.date.setMilliseconds(0);
38 // https://stackoverflow.com/questions/1091372/getting-the-clients-timezone-in-javascript
beccabroek569ccf62018-10-29 13:46:53 -050039 // EDT (UTC - 04:00)
Gunnar Millsb7ea2792018-07-18 13:01:48 -050040 $scope.bmc.timezone =
beccabroek569ccf62018-10-29 13:46:53 -050041 $scope.bmc.date.toString().match(/\(([A-Za-z\s].*)\)/)[1] +
42 ' ' + createOffset($scope.bmc.date);
Gunnar Millsb7ea2792018-07-18 13:01:48 -050043 }
Gunnar Mills2f955bd2018-10-13 16:56:10 -050044 if (data.data[timePath + 'host'] &&
45 data.data[timePath + 'host'].hasOwnProperty('Elapsed')) {
Gunnar Millsb7ea2792018-07-18 13:01:48 -050046 $scope.host.date =
Gunnar Mills2f955bd2018-10-13 16:56:10 -050047 new Date(data.data[timePath + 'host'].Elapsed / 1000);
Gunnar Millsb7ea2792018-07-18 13:01:48 -050048 $scope.host.date.setMilliseconds(0);
49 $scope.host.timezone =
50 $scope.host.date.toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1];
51 }
Gunnar Mills2f955bd2018-10-13 16:56:10 -050052 if (data.data[timePath + 'owner'] &&
53 data.data[timePath + 'owner'].hasOwnProperty('TimeOwner')) {
54 $scope.time.owner =
55 data.data[timePath + 'owner'].TimeOwner.split('.').pop();
Gunnar Millsb7ea2792018-07-18 13:01:48 -050056 }
Gunnar Mills2f955bd2018-10-13 16:56:10 -050057 if (data.data[timePath + 'sync_method'] &&
58 data.data[timePath + 'sync_method'].hasOwnProperty(
Gunnar Millsb7ea2792018-07-18 13:01:48 -050059 'TimeSyncMethod')) {
Gunnar Mills2f955bd2018-10-13 16:56:10 -050060 $scope.time.mode = data.data[timePath + 'sync_method']
Gunnar Millsb7ea2792018-07-18 13:01:48 -050061 .TimeSyncMethod.split('.')
62 .pop();
63 }
Gunnar Mills7de38662018-07-18 13:01:48 -050064 },
65 function(error) {
66 console.log(JSON.stringify(error));
67 });
68
Gunnar Millsb7ea2792018-07-18 13:01:48 -050069 var getNTPPromise = APIUtils.getNTPServers().then(
70 function(data) {
71 $scope.ntp.servers = data.data;
72 },
73 function(error) {
74 console.log(JSON.stringify(error));
75 });
76
77 var promises = [
78 getTimePromise,
79 getNTPPromise,
80 ];
81
82 $q.all(promises).finally(function() {
Gunnar Mills7de38662018-07-18 13:01:48 -050083 $scope.loading = false;
84 });
Gunnar Millsb7ea2792018-07-18 13:01:48 -050085
86 $scope.setTime = function() {
Gunnar Mills2f955bd2018-10-13 16:56:10 -050087 $scope.error = false;
88 $scope.success = false;
Gunnar Millsb7ea2792018-07-18 13:01:48 -050089 $scope.loading = true;
90 var promises = [setTimeMode(), setTimeOwner(), setNTPServers()];
91
92 $q.all(promises).then(
93 function() {
94 // Have to set the time mode and time owner first to avoid a
95 // insufficient permissions if the time mode or time owner had
96 // changed.
97 var manual_promises = [];
Gunnar Mills2f955bd2018-10-13 16:56:10 -050098 if ($scope.time.mode == 'Manual') {
Gunnar Millsb7ea2792018-07-18 13:01:48 -050099 // If owner is 'Split' set both.
100 // If owner is 'Host' set only it.
101 // Else set BMC only. See:
102 // https://github.com/openbmc/phosphor-time-manager/blob/master/README.md
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500103 if ($scope.time.owner != 'Host') {
Gunnar Millseab32132018-09-27 10:07:17 -0500104 manual_promises.push(
105 setBMCTime($scope.bmc.date.getTime() * 1000));
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500106 }
Gunnar Millseab32132018-09-27 10:07:17 -0500107 // Even though we are setting Host time, we are setting from
108 // the BMC date and time fields labeled "BMC and Host Time"
109 // currently.
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500110 if ($scope.time.owner == 'Host') {
Gunnar Millseab32132018-09-27 10:07:17 -0500111 manual_promises.push(
112 setHostTime($scope.bmc.date.getTime() * 1000));
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500113 }
114 }
Gunnar Millseab32132018-09-27 10:07:17 -0500115 // Set the Host if Split even if NTP. In split mode, the host has
116 // its own date and time field. Set from it.
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500117 if ($scope.time.owner == 'Split') {
Gunnar Millseab32132018-09-27 10:07:17 -0500118 manual_promises.push(
119 setHostTime($scope.host.date.getTime() * 1000));
Gunnar Millsf378c772018-09-27 08:53:07 -0500120 }
121
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500122 $q.all(manual_promises)
123 .then(
124 function() {
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500125 $scope.success = true;
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500126 },
127 function(errors) {
128 console.log(JSON.stringify(errors));
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500129 $scope.error = true;
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500130 })
131 .finally(function() {
132 $scope.loading = false;
133 });
134 },
135 function(errors) {
136 console.log(JSON.stringify(errors));
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500137 $scope.error = true;
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500138 $scope.loading = false;
139 });
140 };
141 $scope.refresh = function() {
142 $route.reload();
143 };
144
145 $scope.addNTPField = function() {
146 $scope.ntp.servers.push('');
147 };
148
Gunnar Mills90121f32018-09-16 21:22:45 -0500149 $scope.removeNTPField = function(index) {
150 $scope.ntp.servers.splice(index, 1);
151 };
152
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500153 function setNTPServers() {
154 // Remove any empty strings from the array. Important because we add an
155 // empty string to the end so the user can add a new NTP server, if the
156 // user doesn't fill out the field, we don't want to add.
157 $scope.ntp.servers = $scope.ntp.servers.filter(Boolean);
158 // NTP servers does not allow an empty array, since we remove all empty
159 // strings above, could have an empty array. TODO: openbmc/openbmc#3240
160 if ($scope.ntp.servers.length == 0) {
161 $scope.ntp.servers.push('');
162 }
163 return APIUtils.setNTPServers($scope.ntp.servers);
164 }
165
166 function setTimeMode() {
167 return APIUtils.setTimeMode(
168 'xyz.openbmc_project.Time.Synchronization.Method.' +
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500169 $scope.time.mode);
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500170 }
171
172 function setTimeOwner() {
173 return APIUtils.setTimeOwner(
Gunnar Mills2f955bd2018-10-13 16:56:10 -0500174 'xyz.openbmc_project.Time.Owner.Owners.' + $scope.time.owner);
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500175 }
176
Gunnar Millseab32132018-09-27 10:07:17 -0500177 function setBMCTime(time) {
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500178 // Add the separate date and time objects and convert to Epoch time in
179 // microseconds.
Gunnar Millseab32132018-09-27 10:07:17 -0500180 return APIUtils.setBMCTime(time);
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500181 }
182
Gunnar Millseab32132018-09-27 10:07:17 -0500183 function setHostTime(time) {
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500184 // Add the separate date and time objects and convert to Epoch time
185 // microseconds.
Gunnar Millseab32132018-09-27 10:07:17 -0500186 return APIUtils.setHostTime(time);
Gunnar Millsb7ea2792018-07-18 13:01:48 -0500187 }
beccabroek569ccf62018-10-29 13:46:53 -0500188 function createOffset(date) {
189 // https://stackoverflow.com/questions/9149556/how-to-get-utc-offset-in-javascript-analog-of-timezoneinfo-getutcoffset-in-c
190 var sign = (date.getTimezoneOffset() > 0) ? '-' : '+';
191 var offset = Math.abs(date.getTimezoneOffset());
192 var hours = pad(Math.floor(offset / 60));
193 var minutes = pad(offset % 60);
194 return '(UTC' + sign + hours + ':' + minutes + ')';
195 }
196 function pad(value) {
197 return value < 10 ? '0' + value : value;
198 }
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700199 }
200 ]);
Iftekharul Islamcd789502017-04-19 14:37:55 -0500201})(angular);