1/** 2 * Controller for date-time 3 * 4 * @module app/configuration 5 * @exports dateTimeController 6 * @name dateTimeController 7 */ 8 9window.angular && (function(angular) { 10 'use strict'; 11 12 angular.module('app.configuration').controller('dateTimeController', [ 13 '$scope', '$window', 'APIUtils', '$route', '$q', 14 function($scope, $window, APIUtils, $route, $q) { 15 $scope.bmc = {}; 16 // Only used when the owner is "Split" 17 $scope.host = {}; 18 $scope.ntp = {servers: []}; 19 $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; 25 $scope.loading = true; 26 var timePath = '/xyz/openbmc_project/time/'; 27 28 var getTimePromise = APIUtils.getTime().then( 29 function(data) { 30 // The time is returned as Epoch microseconds convert to 31 // milliseconds. 32 if (data.data[timePath + 'bmc'] && 33 data.data[timePath + 'bmc'].hasOwnProperty('Elapsed')) { 34 $scope.bmc.date = 35 new Date(data.data[timePath + 'bmc'].Elapsed / 1000); 36 // 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 39 // GMT-0400 (EDT) 40 $scope.bmc.timezone = 41 $scope.bmc.date.toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]; 42 } 43 if (data.data[timePath + 'host'] && 44 data.data[timePath + 'host'].hasOwnProperty('Elapsed')) { 45 $scope.host.date = 46 new Date(data.data[timePath + 'host'].Elapsed / 1000); 47 $scope.host.date.setMilliseconds(0); 48 $scope.host.timezone = 49 $scope.host.date.toString().match(/([A-Z]+[\+-][0-9]+.*)/)[1]; 50 } 51 if (data.data[timePath + 'owner'] && 52 data.data[timePath + 'owner'].hasOwnProperty('TimeOwner')) { 53 $scope.time.owner = 54 data.data[timePath + 'owner'].TimeOwner.split('.').pop(); 55 } 56 if (data.data[timePath + 'sync_method'] && 57 data.data[timePath + 'sync_method'].hasOwnProperty( 58 'TimeSyncMethod')) { 59 $scope.time.mode = data.data[timePath + 'sync_method'] 60 .TimeSyncMethod.split('.') 61 .pop(); 62 } 63 }, 64 function(error) { 65 console.log(JSON.stringify(error)); 66 }); 67 68 var getNTPPromise = APIUtils.getNTPServers().then( 69 function(data) { 70 $scope.ntp.servers = data.data; 71 }, 72 function(error) { 73 console.log(JSON.stringify(error)); 74 }); 75 76 var promises = [ 77 getTimePromise, 78 getNTPPromise, 79 ]; 80 81 $q.all(promises).finally(function() { 82 $scope.loading = false; 83 }); 84 85 $scope.setTime = function() { 86 $scope.error = false; 87 $scope.success = false; 88 $scope.loading = true; 89 var promises = [setTimeMode(), setTimeOwner(), setNTPServers()]; 90 91 $q.all(promises).then( 92 function() { 93 // Have to set the time mode and time owner first to avoid a 94 // insufficient permissions if the time mode or time owner had 95 // changed. 96 var manual_promises = []; 97 if ($scope.time.mode == 'Manual') { 98 // If owner is 'Split' set both. 99 // If owner is 'Host' set only it. 100 // Else set BMC only. See: 101 // https://github.com/openbmc/phosphor-time-manager/blob/master/README.md 102 if ($scope.time.owner != 'Host') { 103 manual_promises.push( 104 setBMCTime($scope.bmc.date.getTime() * 1000)); 105 } 106 // Even though we are setting Host time, we are setting from 107 // the BMC date and time fields labeled "BMC and Host Time" 108 // currently. 109 if ($scope.time.owner == 'Host') { 110 manual_promises.push( 111 setHostTime($scope.bmc.date.getTime() * 1000)); 112 } 113 } 114 // Set the Host if Split even if NTP. In split mode, the host has 115 // its own date and time field. Set from it. 116 if ($scope.time.owner == 'Split') { 117 manual_promises.push( 118 setHostTime($scope.host.date.getTime() * 1000)); 119 } 120 121 $q.all(manual_promises) 122 .then( 123 function() { 124 $scope.success = true; 125 }, 126 function(errors) { 127 console.log(JSON.stringify(errors)); 128 $scope.error = true; 129 }) 130 .finally(function() { 131 $scope.loading = false; 132 }); 133 }, 134 function(errors) { 135 console.log(JSON.stringify(errors)); 136 $scope.error = true; 137 $scope.loading = false; 138 }); 139 }; 140 $scope.refresh = function() { 141 $route.reload(); 142 }; 143 144 $scope.addNTPField = function() { 145 $scope.ntp.servers.push(''); 146 }; 147 148 $scope.removeNTPField = function(index) { 149 $scope.ntp.servers.splice(index, 1); 150 }; 151 152 function setNTPServers() { 153 // Remove any empty strings from the array. Important because we add an 154 // empty string to the end so the user can add a new NTP server, if the 155 // user doesn't fill out the field, we don't want to add. 156 $scope.ntp.servers = $scope.ntp.servers.filter(Boolean); 157 // NTP servers does not allow an empty array, since we remove all empty 158 // strings above, could have an empty array. TODO: openbmc/openbmc#3240 159 if ($scope.ntp.servers.length == 0) { 160 $scope.ntp.servers.push(''); 161 } 162 return APIUtils.setNTPServers($scope.ntp.servers); 163 } 164 165 function setTimeMode() { 166 return APIUtils.setTimeMode( 167 'xyz.openbmc_project.Time.Synchronization.Method.' + 168 $scope.time.mode); 169 } 170 171 function setTimeOwner() { 172 return APIUtils.setTimeOwner( 173 'xyz.openbmc_project.Time.Owner.Owners.' + $scope.time.owner); 174 } 175 176 function setBMCTime(time) { 177 // Add the separate date and time objects and convert to Epoch time in 178 // microseconds. 179 return APIUtils.setBMCTime(time); 180 } 181 182 function setHostTime(time) { 183 // Add the separate date and time objects and convert to Epoch time 184 // microseconds. 185 return APIUtils.setHostTime(time); 186 } 187 } 188 ]); 189})(angular); 190