460
461
self.add_resource_template_attributes(resource)
464
def is_hwe_resource(self, resource):
465
"""Return True if the resource is an Ubuntu HWE resource."""
466
if resource.rtype != BOOT_RESOURCE_TYPE.SYNCED:
468
if not resource.name.startswith('ubuntu/'):
470
arch, subarch = resource.split_arch()
471
return subarch.startswith('hwe-')
473
def pick_latest_datetime(self, time, other_time):
474
"""Return the datetime that is the latest."""
477
return max([time, other_time])
479
def calculate_unique_size_for_resources(self, resources):
480
"""Return size of all unique largefiles for the given resources."""
483
for resource in resources:
484
resource_set = resource.get_latest_set()
485
if resource_set is None:
487
for rfile in resource_set.files.all():
489
largefile = rfile.largefile
490
except LargeFile.DoesNotExist:
492
if largefile.sha256 not in shas:
493
size += largefile.total_size
494
shas.add(largefile.sha256)
497
def are_all_resources_complete(self, resources):
498
"""Return the complete status for all the given resources."""
499
for resource in resources:
500
resource_set = resource.get_latest_set()
501
if resource_set is None:
503
if not resource_set.complete:
507
def get_last_update_for_resources(self, resources):
508
"""Return the latest updated time for all resources."""
510
for resource in resources:
511
last_update = self.pick_latest_datetime(
512
last_update, resource.updated)
513
resource_set = resource.get_latest_set()
514
if resource_set is not None:
515
last_update = self.pick_latest_datetime(
516
last_update, resource_set.updated)
519
def get_number_of_nodes_for_resources(self, resources):
520
"""Return the number of nodes used by all resources."""
522
self.get_number_of_nodes_deployed_for(resource)
523
for resource in resources])
525
def get_progress_for_resources(self, resources):
526
"""Return the overall progress for all resources."""
529
for resource in resources:
530
resource_set = resource.get_latest_set()
531
if resource_set is not None:
532
size += resource_set.size
533
total_size += resource_set.total_size
535
# Handle division by zero
537
return 100.0 * (size / float(total_size))
539
def hwes_to_resource(self, hwes):
540
"""Convert the list of hwes into one resource to be used in the UI."""
541
# Calculate all of the values using all of the hwe resources for
542
# this combination of resources.
543
last_update = self.get_last_update_for_resources(hwes)
544
unique_size = self.calculate_unique_size_for_resources(hwes)
545
number_of_nodes = self.get_number_of_nodes_for_resources(hwes)
546
complete = self.are_all_resources_complete(hwes)
547
progress = self.get_progress_for_resources(hwes)
549
# Set the computed attributes on the first resource as that will
550
# be the only one returned to the UI.
552
resource.arch, resource.subarch = resource.split_arch()
553
resource.title = self.get_resource_title(resource)
554
resource.complete = complete
555
resource.size = format_size(unique_size)
556
resource.last_update = last_update
557
resource.number_of_nodes = number_of_nodes
558
resource.complete = complete
561
resource.status = "Downloading %3.0f%%" % progress
562
resource.downloading = True
564
resource.status = "Queued for download"
565
resource.downloading = False
567
# See if all the hwe resources exist on all the clusters.
568
cluster_has_hwes = any(
569
hwe in hwes for hwe in self.cluster_resources)
571
resource.status = "Complete"
572
resource.downloading = False
574
resource.complete = False
575
if self.clusters_syncing:
576
resource.status = "Syncing to clusters"
577
resource.downloading = True
579
resource.status = "Waiting for clusters to sync"
580
resource.downloading = False
583
def combine_hwe_resources(self, resources):
584
"""Return a list of resources removing the duplicate hwe resources."""
585
none_hwe_resources = []
586
hwe_resources = defaultdict(list)
587
for resource in resources:
588
if not self.is_hwe_resource(resource):
589
self.add_resource_template_attributes(resource)
590
none_hwe_resources.append(resource)
592
arch = resource.split_arch()[0]
593
key = '%s/%s' % (resource.name, arch)
594
hwe_resources[key].append(resource)
596
self.hwes_to_resource(hwes)
597
for _, hwes in hwe_resources.items()
599
return none_hwe_resources + combined_hwes
463
601
def ajax(self, request, *args, **kwargs):
464
602
"""Return all resources in a json object.
466
604
This is used by the image model list on the client side to update
467
605
the status of images."""
468
resources = list(BootResource.objects.all())
469
for resource in resources:
470
self.add_resource_template_attributes(resource)
606
resources = self.combine_hwe_resources(BootResource.objects.all())
471
607
json_resources = [