github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/public/static/js/distros.js (about) 1 mciModule.controller('DistrosCtrl', function($scope, $window, $location, mciDistroRestService) { 2 3 $scope.readOnly = !$window.isSuperUser; 4 5 $scope.distros = $window.distros; 6 for (var i = 0; i < $scope.distros.length; i++) { 7 $scope.distros[i].pool_size = $scope.distros[i].pool_size || 0; 8 } 9 10 $scope.providers = [{ 11 'id': 'ec2', 12 'display': 'EC2 (On-Demand Instance)' 13 }, { 14 'id': 'ec2-spot', 15 'display': 'EC2 (Spot Instance)' 16 }, { 17 'id': 'static', 18 'display': 'Static IP/VM' 19 }, { 20 'id': 'digitalocean', 21 'display': 'Digital Ocean' 22 }, { 23 'id': 'docker', 24 'display': 'Docker' 25 }]; 26 27 $scope.architectures = [{ 28 'id': 'windows_amd64', 29 'display': 'Windows 64-bit' 30 }, { 31 'id': 'linux_ppc64le', 32 'display': 'Linux PowerPC 64-bit' 33 }, { 34 'id': 'linux_s390x', 35 'display': 'Linux zSeries' 36 }, { 37 'id': 'linux_arm64', 38 'display': 'Linux ARM 64-bit' 39 }, { 40 'id': 'windows_386', 41 'display': 'Windows 32-bit' 42 }, { 43 'id': 'darwin_amd64', 44 'display': 'OSX 64-bit' 45 }, { 46 'id': 'darwin_386', 47 'display': 'OSX 32-bit' 48 }, { 49 'id': 'linux_amd64', 50 'display': 'Linux 64-bit' 51 }, { 52 'id': 'linux_386', 53 'display': 'Linux 32-bit' 54 }, { 55 'id': 'solaris_amd64', 56 'display': 'Solaris 64-bit' 57 }]; 58 59 $scope.ids = []; 60 61 $scope.keys = []; 62 63 $scope.modalOpen = false; 64 65 $scope.$on('$locationChangeStart', function(event) { 66 $scope.hashLoad(); 67 }); 68 69 $scope.hashLoad = function() { 70 var distroHash = $location.hash(); 71 if (distroHash) { 72 // If the distro exists, load it. 73 var distro = $scope.getDistroById(distroHash); 74 if (distro) { 75 $scope.activeDistro = distro; 76 return; 77 } 78 } 79 // Default to the first distro. 80 $scope.setActiveDistro($scope.distros[0]); 81 }; 82 83 $scope.setActiveDistro = function(distro) { 84 $scope.activeDistro = distro; 85 $location.hash(distro._id); 86 }; 87 88 $scope.getDistroById = function(id) { 89 return _.find($scope.distros, function(distro) { 90 return distro._id === id; 91 }); 92 }; 93 94 $scope.initOptions = function() { 95 var keys = []; 96 97 if ($window.keys !== null) { 98 keys = Object.keys($window.keys); 99 } 100 101 for (var i = 0; i < $scope.distros.length; i++) { 102 $scope.ids.push($scope.distros[i]._id); 103 } 104 105 for (var i = 0; i < keys.length; i++) { 106 $scope.keys.push({ 107 name: keys[i], 108 location: $window.keys[keys[i]], 109 }); 110 } 111 }; 112 113 $scope.isUnique = function(id) { 114 return $scope.ids.indexOf(id) == -1; 115 }; 116 117 $scope.setKeyValue = function(key, value) { 118 $scope.activeDistro[key] = value; 119 }; 120 121 $scope.getKeyDisplay = function(key, display) { 122 for (var i = 0; i < $scope[key].length; i++) { 123 if ($scope[key][i].id === display) { 124 return $scope[key][i].display; 125 } 126 } 127 return display; 128 }; 129 130 $scope.addHost = function() { 131 if ($scope.activeDistro.settings == null) { 132 $scope.activeDistro.settings = {}; 133 } 134 if ($scope.activeDistro.settings.hosts == null) { 135 $scope.activeDistro.settings.hosts = []; 136 } 137 $scope.activeDistro.settings.hosts.push({}); 138 $scope.scrollElement('#hosts-table'); 139 } 140 141 $scope.removeHost = function(host) { 142 var index = $scope.activeDistro.settings.hosts.indexOf(host); 143 $scope.activeDistro.settings.hosts.splice(index, 1); 144 } 145 146 $scope.addMount = function(mount_point) { 147 if ($scope.activeDistro.settings == null) { 148 $scope.activeDistro.settings = {}; 149 } 150 if ($scope.activeDistro.settings.mount_points == null) { 151 $scope.activeDistro.settings.mount_points = []; 152 } 153 $scope.activeDistro.settings.mount_points.push({}); 154 $scope.scrollElement('#mounts-table'); 155 } 156 157 $scope.scrollElement = function(elt) { 158 $(elt).animate({ 159 scrollTop: $(elt)[0].scrollHeight 160 }, 'slow'); 161 } 162 163 $scope.removeMount = function(mount_point) { 164 var index = $scope.activeDistro.settings.mount_points.indexOf(mount_point); 165 $scope.activeDistro.settings.mount_points.splice(index, 1); 166 } 167 168 $scope.addSSHOption = function() { 169 if ($scope.activeDistro.ssh_options == null) { 170 $scope.activeDistro.ssh_options = []; 171 } 172 $scope.activeDistro.ssh_options.push(''); 173 $scope.scrollElement('#ssh-options-table'); 174 } 175 176 $scope.removeSSHOption = function(ssh_option) { 177 var index = $scope.activeDistro.ssh_options.indexOf(ssh_option); 178 $scope.activeDistro.ssh_options.splice(index, 1); 179 } 180 181 $scope.addExpansion = function(expansion) { 182 if ($scope.activeDistro.expansions == null) { 183 $scope.activeDistro.expansions = []; 184 } 185 $scope.activeDistro.expansions.push({}); 186 $scope.scrollElement('#expansions-table'); 187 } 188 189 $scope.removeExpansion = function(expansion) { 190 var index = $scope.activeDistro.expansions.indexOf(expansion); 191 $scope.activeDistro.expansions.splice(index, 1); 192 } 193 194 $scope.saveConfiguration = function() { 195 if ($scope.activeDistro.new) { 196 mciDistroRestService.addDistro( 197 $scope.activeDistro, { 198 success: function(distros, status) { 199 $window.location.reload(true); 200 }, 201 error: function(jqXHR, status, errorThrown) { 202 $window.location.reload(true); 203 console.log(jqXHR); 204 } 205 } 206 ); 207 } else { 208 mciDistroRestService.modifyDistro( 209 $scope.activeDistro._id, 210 $scope.activeDistro, 211 $scope.shouldDeco, 212 { 213 success: function(distros, status) { 214 $window.location.reload(true); 215 }, 216 error: function(jqXHR, status, errorThrown) { 217 $window.location.reload(true); 218 console.log(jqXHR); 219 } 220 } 221 ); 222 } 223 // this will reset the location hash to the new one in case the _id is changed. 224 $scope.setActiveDistro($scope.activeDistro) 225 }; 226 227 $scope.removeConfiguration = function() { 228 mciDistroRestService.removeDistro( 229 $scope.activeDistro._id, 230 $scope.shouldDeco, 231 { 232 success: function(distros, status) { 233 $window.location.reload(true); 234 }, 235 error: function(jqXHR, status, errorThrown) { 236 $window.location.reload(true); 237 console.log(jqXHR); 238 } 239 } 240 ); 241 }; 242 243 $scope.newDistro = function() { 244 if (!$scope.hasNew) { 245 var defaultOptions = { 246 '_id': 'new distro', 247 'arch': 'linux_amd64', 248 'provider': 'ec2', 249 'new': true, 250 }; 251 252 if ($scope.keys.length != 0) { 253 defaultOptions.ssh_key = $scope.keys[0].name; 254 } 255 $scope.distros.unshift(defaultOptions); 256 $scope.hasNew = true; 257 } 258 $scope.setActiveDistro($scope.distros[0]); 259 $('#distros-list-container').animate({ scrollTop: 0 }, 'slow'); 260 $anchorScroll(); 261 }; 262 263 $scope.copyDistro = function(){ 264 if (!$scope.hasNew) { 265 var newDistro = { 266 'arch': $scope.activeDistro.arch, 267 'work_dir': $scope.activeDistro.work_dir, 268 'provider': $scope.activeDistro.provider, 269 'new': true, 270 'user': $scope.activeDistro.user, 271 'ssh_key': $scope.activeDistro.ssh_key, 272 'ssh_options': $scope.activeDistro.ssh_options, 273 'setup': $scope.activeDistro.setup, 274 'pool_size': $scope.activeDistro.pool_size, 275 'setup_as_sudo' : $scope.activeDistro.setup_as_sudo, 276 277 } 278 newDistro.settings = _.clone($scope.activeDistro.settings); 279 newDistro.expansions = _.clone($scope.activeDistro.expansions); 280 281 $scope.distros.unshift(newDistro); 282 $scope.hasNew = true; 283 $scope.setActiveDistro($scope.distros[0]); 284 $('#distros-list-container').animate({ scrollTop: 0 }, 'slow'); 285 $anchorScroll(); 286 } 287 } 288 289 290 $scope.openConfirmationModal = function(option) { 291 $scope.confirmationOption = option; 292 $scope.modalTitle = 'Configuration'; 293 var modal = $('#admin-modal').modal('show'); 294 295 if (option === 'removeDistro') { 296 if (modal.data('bs.modal').isShown) { 297 $scope.modalOpen = true; 298 } else { 299 $scope.modalOpen = false; 300 } 301 } 302 303 $(document).keyup(function(ev) { 304 if ($scope.modalOpen && ev.keyCode === 13) { 305 if ($scope.confirmationOption === 'removeDistro') { 306 $scope.removeConfiguration(); 307 $('#admin-modal').modal('hide'); 308 } 309 } 310 }); 311 } 312 313 $scope.checkPortRange = function(min, max) { 314 if ($scope.form.portRange.minPort.$invalid || $scope.form.portRange.maxPort.$invalid) { 315 return false 316 } 317 return (!min && !max) || (min >= 0 && min <= max); 318 } 319 320 // checks that the form is valid for the given active distro 321 $scope.validForm = function() { 322 if ($scope.activeDistro.provider == 'ec2' || $scope.activeDistro.provider == 'ec2-spot'){ 323 return $scope.validSecurityGroup() && $scope.validSubnetId; 324 } 325 return true; 326 } 327 328 // if a security group is in a vpc it needs to be the id which starts with 'sg-' 329 $scope.validSecurityGroup = function(){ 330 if ($scope.activeDistro){ 331 if ($scope.activeDistro.settings.is_vpc){ 332 return $scope.activeDistro.settings.security_group.substring(0,3) == 'sg-'; 333 } 334 } 335 return true 336 }; 337 338 // if a security group is in a vpc it needs to be the id which starts with 'subnet-' 339 $scope.validSubnetId = function(){ 340 if ($scope.activeDistro){ 341 if ($scope.activeDistro.settings.is_vpc) { 342 return $scope.activeDistro.settings.subnet_id.substring(0,7) == 'subnet-'; 343 } 344 } 345 return true 346 }; 347 348 // scroll to top of window on page reload 349 $(window).on('beforeunload', function() { 350 $(window).scrollTop(0); 351 }); 352 353 }); 354 355 mciModule.directive('removeDistro', function() { 356 return { 357 restrict: 'E', 358 template: '<div class="row">' + 359 ' <div class="col-lg-12">' + 360 ' <div>' + 361 ' Are you sure you want to remove [[activeDistro._id]]?' + 362 ' <div style="float:right">' + 363 ' <button type="button" class="btn btn-danger" style="float: right;" data-dismiss="modal">Cancel</button>' + 364 ' <button type="button" class="btn btn-primary" style="float: right; margin-right: 10px;" ng-click="removeConfiguration()">Yes</button>' + 365 ' </div>' + 366 ' </div>' + 367 ' </div>' + 368 '</div>' 369 } 370 }); 371 372 mciModule.filter("providerDisplay", function() { 373 return function(provider, scope) { 374 return scope.getKeyDisplay('providers', provider); 375 } 376 }); 377 378 mciModule.filter("archDisplay", function() { 379 return function(arch, scope) { 380 return scope.getKeyDisplay('architectures', arch); 381 } 382 }); 383 384 mciModule.directive('unique', function() { 385 return { 386 require: 'ngModel', 387 link: function(scope, elm, attrs, ctrl) { 388 ctrl.$parsers.unshift(function(value) { 389 var valid = scope.isUnique(value); 390 ctrl.$setValidity('unique', valid); 391 return value; 392 }); 393 ctrl.$formatters.unshift(function(value) { 394 var valid = scope.isUnique(value); 395 ctrl.$setValidity('unique', valid); 396 return value; 397 }); 398 } 399 }; 400 }); 401