diff options
Diffstat (limited to 'bitbake/lib/bb/ui/buildinfohelper.py')
-rw-r--r-- | bitbake/lib/bb/ui/buildinfohelper.py | 85 |
1 files changed, 56 insertions, 29 deletions
diff --git a/bitbake/lib/bb/ui/buildinfohelper.py b/bitbake/lib/bb/ui/buildinfohelper.py index 8bdc9cc0a7..a5b22379aa 100644 --- a/bitbake/lib/bb/ui/buildinfohelper.py +++ b/bitbake/lib/bb/ui/buildinfohelper.py | |||
@@ -37,7 +37,7 @@ os.environ["DJANGO_SETTINGS_MODULE"] =\ | |||
37 | django.setup() | 37 | django.setup() |
38 | 38 | ||
39 | from orm.models import Build, Task, Recipe, Layer_Version, Layer, Target, LogMessage, HelpText | 39 | from orm.models import Build, Task, Recipe, Layer_Version, Layer, Target, LogMessage, HelpText |
40 | from orm.models import Target_Image_File, BuildArtifact | 40 | from orm.models import Target_Image_File, BuildArtifact, TargetArtifactFile |
41 | from orm.models import Variable, VariableHistory | 41 | from orm.models import Variable, VariableHistory |
42 | from orm.models import Package, Package_File, Target_Installed_Package, Target_File | 42 | from orm.models import Package, Package_File, Target_Installed_Package, Target_File |
43 | from orm.models import Task_Dependency, Package_Dependency | 43 | from orm.models import Task_Dependency, Package_Dependency |
@@ -121,6 +121,13 @@ class ORMWrapper(object): | |||
121 | 121 | ||
122 | return vars(self)[dictname][key] | 122 | return vars(self)[dictname][key] |
123 | 123 | ||
124 | def get_similar_target_with_image_files(self, target): | ||
125 | """ | ||
126 | Get a Target object "similar" to target; i.e. with the same target | ||
127 | name ('core-image-minimal' etc.) and machine. | ||
128 | """ | ||
129 | return target.get_similar_target_with_image_files() | ||
130 | |||
124 | def _timestamp_to_datetime(self, secs): | 131 | def _timestamp_to_datetime(self, secs): |
125 | """ | 132 | """ |
126 | Convert timestamp in seconds to Python datetime | 133 | Convert timestamp in seconds to Python datetime |
@@ -678,27 +685,32 @@ class ORMWrapper(object): | |||
678 | file_name = file_name, | 685 | file_name = file_name, |
679 | file_size = file_size) | 686 | file_size = file_size) |
680 | 687 | ||
681 | def save_artifact_information_no_dedupe(self, build_obj, file_name, file_size): | 688 | def save_target_artifact_file(self, target_obj, file_name, file_size): |
682 | """ | 689 | """ |
683 | Save artifact information without checking for duplicate paths; | 690 | Save artifact file information for a Target target_obj. |
684 | this is used when we are saving data about an artifact which was | 691 | |
685 | generated by a previous build but which is also relevant to this build, | 692 | Note that this doesn't include SDK artifacts, only images and |
686 | e.g. a bzImage file. | 693 | related files (e.g. bzImage). |
687 | """ | 694 | """ |
688 | BuildArtifact.objects.create(build=build_obj, file_name=file_name, | 695 | TargetArtifactFile.objects.create(target=target_obj, |
689 | file_size=file_size) | 696 | file_name=file_name, file_size=file_size) |
690 | 697 | ||
691 | def save_artifact_information(self, build_obj, file_name, file_size): | 698 | def save_artifact_information(self, build_obj, file_name, file_size): |
692 | # we skip the image files from other builds | 699 | """ |
693 | if Target_Image_File.objects.filter(file_name = file_name).count() > 0: | 700 | TODO this is currently used to save SDK artifacts to the database, |
694 | return | 701 | but will be replaced in future once SDK artifacts are associated with |
695 | 702 | Target objects (as they eventually should be) | |
703 | """ | ||
696 | # do not update artifacts found in other builds | 704 | # do not update artifacts found in other builds |
697 | if BuildArtifact.objects.filter(file_name = file_name).count() > 0: | 705 | if BuildArtifact.objects.filter(file_name = file_name).count() > 0: |
698 | return | 706 | return |
699 | 707 | ||
700 | self.save_artifact_information_no_dedupe(self, build_obj, file_name, | 708 | # do not update artifact if already a target artifact file for that path |
701 | file_size) | 709 | if TargetArtifactFile.objects.filter(file_name = file_name).count() > 0: |
710 | return | ||
711 | |||
712 | BuildArtifact.objects.create(build=build_obj, file_name=file_name, | ||
713 | file_size=file_size) | ||
702 | 714 | ||
703 | def create_logmessage(self, log_information): | 715 | def create_logmessage(self, log_information): |
704 | assert 'build' in log_information | 716 | assert 'build' in log_information |
@@ -1496,7 +1508,7 @@ class BuildInfoHelper(object): | |||
1496 | 1508 | ||
1497 | self.orm_wrapper.create_logmessage(log_information) | 1509 | self.orm_wrapper.create_logmessage(log_information) |
1498 | 1510 | ||
1499 | def _get_files_from_image_license(self, image_license_manifest_path): | 1511 | def _get_filenames_from_image_license(self, image_license_manifest_path): |
1500 | """ | 1512 | """ |
1501 | Find the FILES line in the image_license.manifest file, | 1513 | Find the FILES line in the image_license.manifest file, |
1502 | which has the basenames of the bzImage and modules files | 1514 | which has the basenames of the bzImage and modules files |
@@ -1567,19 +1579,20 @@ class BuildInfoHelper(object): | |||
1567 | 1579 | ||
1568 | OR | 1580 | OR |
1569 | 1581 | ||
1570 | 2. There are no files for the target, so copy them from a | 1582 | 2. There are no new files for the target (they were already produced by |
1571 | previous build with the same target + machine. | 1583 | a previous build), so copy them from the most recent previous build with |
1584 | the same target, task and machine. | ||
1572 | """ | 1585 | """ |
1573 | deploy_dir_image = \ | 1586 | deploy_dir_image = \ |
1574 | self.server.runCommand(['getVariable', 'DEPLOY_DIR_IMAGE'])[0] | 1587 | self.server.runCommand(['getVariable', 'DEPLOY_DIR_IMAGE'])[0] |
1575 | 1588 | ||
1576 | # if there's no DEPLOY_DIR_IMAGE, there aren't going to be | 1589 | # if there's no DEPLOY_DIR_IMAGE, there aren't going to be |
1577 | # any build artifacts, so we can return immediately | 1590 | # any image artifacts, so we can return immediately |
1578 | if not deploy_dir_image: | 1591 | if not deploy_dir_image: |
1579 | return | 1592 | return |
1580 | 1593 | ||
1581 | buildname = self.server.runCommand(['getVariable', 'BUILDNAME'])[0] | 1594 | buildname = self.server.runCommand(['getVariable', 'BUILDNAME'])[0] |
1582 | machine = self.server.runCommand(['getVariable', 'MACHINE'])[0] | 1595 | machine = self.server.runCommand(['getVariable', 'MACHINE'])[0] |
1583 | image_name = self.server.runCommand(['getVariable', 'IMAGE_NAME'])[0] | 1596 | image_name = self.server.runCommand(['getVariable', 'IMAGE_NAME'])[0] |
1584 | 1597 | ||
1585 | # location of the image_license.manifest files for this build; | 1598 | # location of the image_license.manifest files for this build; |
@@ -1597,7 +1610,10 @@ class BuildInfoHelper(object): | |||
1597 | image_file_extensions_unique = set(image_file_extensions.split(' ')) | 1610 | image_file_extensions_unique = set(image_file_extensions.split(' ')) |
1598 | 1611 | ||
1599 | targets = self.internal_state['targets'] | 1612 | targets = self.internal_state['targets'] |
1613 | |||
1614 | # filter out anything which isn't an image target | ||
1600 | image_targets = [target for target in targets if target.is_image] | 1615 | image_targets = [target for target in targets if target.is_image] |
1616 | |||
1601 | for target in image_targets: | 1617 | for target in image_targets: |
1602 | # this is set to True if we find at least one file relating to | 1618 | # this is set to True if we find at least one file relating to |
1603 | # this target; if this remains False after the scan, we copy the | 1619 | # this target; if this remains False after the scan, we copy the |
@@ -1625,16 +1641,17 @@ class BuildInfoHelper(object): | |||
1625 | if os.path.isfile(image_license_manifest_path): | 1641 | if os.path.isfile(image_license_manifest_path): |
1626 | has_files = True | 1642 | has_files = True |
1627 | 1643 | ||
1628 | basenames = self._get_files_from_image_license( | 1644 | basenames = self._get_filenames_from_image_license( |
1629 | image_license_manifest_path) | 1645 | image_license_manifest_path) |
1630 | 1646 | ||
1631 | for basename in basenames: | 1647 | for basename in basenames: |
1632 | artifact_path = os.path.join(deploy_dir_image, basename) | 1648 | artifact_path = os.path.join(deploy_dir_image, basename) |
1633 | artifact_size = os.stat(artifact_path).st_size | 1649 | artifact_size = os.stat(artifact_path).st_size |
1634 | 1650 | ||
1635 | self.orm_wrapper.save_artifact_information_no_dedupe( | 1651 | # note that the artifact will only be saved against this |
1636 | self.internal_state['build'], artifact_path, | 1652 | # build if it hasn't been already |
1637 | artifact_size) | 1653 | self.orm_wrapper.save_target_artifact_file(target, |
1654 | artifact_path, artifact_size) | ||
1638 | 1655 | ||
1639 | # store the license manifest path on the target | 1656 | # store the license manifest path on the target |
1640 | # (this file is also created any time an image file is created) | 1657 | # (this file is also created any time an image file is created) |
@@ -1648,7 +1665,10 @@ class BuildInfoHelper(object): | |||
1648 | # (via real_image_name); note that we don't have to set | 1665 | # (via real_image_name); note that we don't have to set |
1649 | # has_files = True, as searching for the license manifest file | 1666 | # has_files = True, as searching for the license manifest file |
1650 | # will already have set it to true if at least one image file was | 1667 | # will already have set it to true if at least one image file was |
1651 | # produced | 1668 | # produced; note that the real_image_name includes BUILDNAME, which |
1669 | # in turn includes a timestamp; so if no files were produced for | ||
1670 | # this timestamp (i.e. the build reused existing image files already | ||
1671 | # in the directory), no files will be recorded against this target | ||
1652 | image_files = self._get_image_files(deploy_dir_image, | 1672 | image_files = self._get_image_files(deploy_dir_image, |
1653 | real_image_name, image_file_extensions_unique) | 1673 | real_image_name, image_file_extensions_unique) |
1654 | 1674 | ||
@@ -1657,11 +1677,18 @@ class BuildInfoHelper(object): | |||
1657 | target, image_file['path'], image_file['size']) | 1677 | target, image_file['path'], image_file['size']) |
1658 | 1678 | ||
1659 | if not has_files: | 1679 | if not has_files: |
1660 | # TODO copy artifact and image files from the | 1680 | # copy image files and build artifacts from the |
1661 | # most-recently-built Target with the same target + machine | 1681 | # most-recently-built Target with the |
1662 | # as this Target; also copy the license manifest path, | 1682 | # same target + machine as this Target; also copy the license |
1663 | # as that is treated differently | 1683 | # manifest path, as that is not treated as an artifact and needs |
1664 | pass | 1684 | # to be set separately |
1685 | most_recent = \ | ||
1686 | self.orm_wrapper.get_similar_target_with_image_files(target) | ||
1687 | |||
1688 | if most_recent: | ||
1689 | logger.info('image artifacts for target %s cloned from ' \ | ||
1690 | 'target %s' % (target.pk, most_recent.pk)) | ||
1691 | target.clone_artifacts_from(most_recent) | ||
1665 | 1692 | ||
1666 | def close(self, errorcode): | 1693 | def close(self, errorcode): |
1667 | if self.brbe is not None: | 1694 | if self.brbe is not None: |