... |
... |
@@ -85,7 +85,8 @@ import shutil |
85
|
85
|
from . import _yaml
|
86
|
86
|
from ._variables import Variables
|
87
|
87
|
from ._versions import BST_CORE_ARTIFACT_VERSION
|
88
|
|
-from ._exceptions import BstError, LoadError, LoadErrorReason, ImplError, ErrorDomain
|
|
88
|
+from ._exceptions import BstError, LoadError, LoadErrorReason, ImplError, \
|
|
89
|
+ ErrorDomain, SandboxError
|
89
|
90
|
from .utils import UtilError
|
90
|
91
|
from . import Plugin, Consistency, Scope
|
91
|
92
|
from . import SandboxFlags
|
... |
... |
@@ -1554,6 +1555,8 @@ class Element(Plugin): |
1554
|
1555
|
|
1555
|
1556
|
# Call the abstract plugin methods
|
1556
|
1557
|
collect = None
|
|
1558
|
+ save_artifacts = True
|
|
1559
|
+
|
1557
|
1560
|
try:
|
1558
|
1561
|
# Step 1 - Configure
|
1559
|
1562
|
self.configure_sandbox(sandbox)
|
... |
... |
@@ -1565,6 +1568,9 @@ class Element(Plugin): |
1565
|
1568
|
collect = self.assemble(sandbox) # pylint: disable=assignment-from-no-return
|
1566
|
1569
|
self.__set_build_result(success=True, description="succeeded")
|
1567
|
1570
|
except BstError as e:
|
|
1571
|
+ if isinstance(e, SandboxError):
|
|
1572
|
+ save_artifacts = False
|
|
1573
|
+
|
1568
|
1574
|
# Shelling into a sandbox is useful to debug this error
|
1569
|
1575
|
e.sandbox = True
|
1570
|
1576
|
|
... |
... |
@@ -1592,100 +1598,108 @@ class Element(Plugin): |
1592
|
1598
|
self.__set_build_result(success=False, description=str(e), detail=e.detail)
|
1593
|
1599
|
raise
|
1594
|
1600
|
finally:
|
1595
|
|
- if collect is not None:
|
1596
|
|
- try:
|
1597
|
|
- sandbox_vroot = sandbox.get_virtual_directory()
|
1598
|
|
- collectvdir = sandbox_vroot.descend(collect.lstrip(os.sep).split(os.sep))
|
1599
|
|
- except VirtualDirectoryError:
|
1600
|
|
- # No collect directory existed
|
1601
|
|
- collectvdir = None
|
1602
|
|
-
|
1603
|
|
- # Create artifact directory structure
|
1604
|
|
- assembledir = os.path.join(rootdir, 'artifact')
|
1605
|
|
- filesdir = os.path.join(assembledir, 'files')
|
1606
|
|
- logsdir = os.path.join(assembledir, 'logs')
|
1607
|
|
- metadir = os.path.join(assembledir, 'meta')
|
1608
|
|
- buildtreedir = os.path.join(assembledir, 'buildtree')
|
1609
|
|
- os.mkdir(assembledir)
|
1610
|
|
- if collect is not None and collectvdir is not None:
|
1611
|
|
- os.mkdir(filesdir)
|
1612
|
|
- os.mkdir(logsdir)
|
1613
|
|
- os.mkdir(metadir)
|
1614
|
|
- os.mkdir(buildtreedir)
|
1615
|
|
-
|
1616
|
|
- # Hard link files from collect dir to files directory
|
1617
|
|
- if collect is not None and collectvdir is not None:
|
1618
|
|
- collectvdir.export_files(filesdir, can_link=True)
|
1619
|
|
-
|
1620
|
|
- try:
|
1621
|
|
- sandbox_vroot = sandbox.get_virtual_directory()
|
1622
|
|
- sandbox_build_dir = sandbox_vroot.descend(
|
1623
|
|
- self.get_variable('build-root').lstrip(os.sep).split(os.sep))
|
1624
|
|
- # Hard link files from build-root dir to buildtreedir directory
|
1625
|
|
- sandbox_build_dir.export_files(buildtreedir)
|
1626
|
|
- except VirtualDirectoryError:
|
1627
|
|
- # Directory could not be found. Pre-virtual
|
1628
|
|
- # directory behaviour was to continue silently
|
1629
|
|
- # if the directory could not be found.
|
1630
|
|
- pass
|
1631
|
|
-
|
1632
|
|
- # Copy build log
|
1633
|
|
- log_filename = context.get_log_filename()
|
1634
|
|
- self._build_log_path = os.path.join(logsdir, 'build.log')
|
1635
|
|
- if log_filename:
|
1636
|
|
- shutil.copyfile(log_filename, self._build_log_path)
|
1637
|
|
-
|
1638
|
|
- # Store public data
|
1639
|
|
- _yaml.dump(_yaml.node_sanitize(self.__dynamic_public), os.path.join(metadir, 'public.yaml'))
|
1640
|
|
-
|
1641
|
|
- # Store result
|
1642
|
|
- build_result_dict = {"success": self.__build_result[0], "description": self.__build_result[1]}
|
1643
|
|
- if self.__build_result[2] is not None:
|
1644
|
|
- build_result_dict["detail"] = self.__build_result[2]
|
1645
|
|
- _yaml.dump(build_result_dict, os.path.join(metadir, 'build-result.yaml'))
|
1646
|
|
-
|
1647
|
|
- # ensure we have cache keys
|
1648
|
|
- self._assemble_done()
|
1649
|
|
-
|
1650
|
|
- # Store keys.yaml
|
1651
|
|
- _yaml.dump(_yaml.node_sanitize({
|
1652
|
|
- 'strong': self._get_cache_key(),
|
1653
|
|
- 'weak': self._get_cache_key(_KeyStrength.WEAK),
|
1654
|
|
- }), os.path.join(metadir, 'keys.yaml'))
|
1655
|
|
-
|
1656
|
|
- # Store dependencies.yaml
|
1657
|
|
- _yaml.dump(_yaml.node_sanitize({
|
1658
|
|
- e.name: e._get_cache_key() for e in self.dependencies(Scope.BUILD)
|
1659
|
|
- }), os.path.join(metadir, 'dependencies.yaml'))
|
1660
|
|
-
|
1661
|
|
- # Store workspaced.yaml
|
1662
|
|
- _yaml.dump(_yaml.node_sanitize({
|
1663
|
|
- 'workspaced': True if self._get_workspace() else False
|
1664
|
|
- }), os.path.join(metadir, 'workspaced.yaml'))
|
1665
|
|
-
|
1666
|
|
- # Store workspaced-dependencies.yaml
|
1667
|
|
- _yaml.dump(_yaml.node_sanitize({
|
1668
|
|
- 'workspaced-dependencies': [
|
1669
|
|
- e.name for e in self.dependencies(Scope.BUILD)
|
1670
|
|
- if e._get_workspace()
|
1671
|
|
- ]
|
1672
|
|
- }), os.path.join(metadir, 'workspaced-dependencies.yaml'))
|
1673
|
|
-
|
1674
|
|
- with self.timed_activity("Caching artifact"):
|
1675
|
|
- artifact_size = utils._get_dir_size(assembledir)
|
1676
|
|
- self.__artifacts.commit(self, assembledir, self.__get_cache_keys_for_commit())
|
1677
|
|
-
|
1678
|
|
- if collect is not None and collectvdir is None:
|
1679
|
|
- raise ElementError(
|
1680
|
|
- "Directory '{}' was not found inside the sandbox, "
|
1681
|
|
- "unable to collect artifact contents"
|
1682
|
|
- .format(collect))
|
|
1601
|
+ if save_artifacts:
|
|
1602
|
+ artifact_size = self._cache_artifact(rootdir, sandbox, context, collect)
|
|
1603
|
+ else:
|
|
1604
|
+ artifact_size = 0
|
1683
|
1605
|
|
1684
|
1606
|
# Finally cleanup the build dir
|
1685
|
1607
|
cleanup_rootdir()
|
1686
|
1608
|
|
1687
|
1609
|
return artifact_size
|
1688
|
1610
|
|
|
1611
|
+ def _cache_artifact(self, rootdir, sandbox, context, collect):
|
|
1612
|
+ if collect is not None:
|
|
1613
|
+ try:
|
|
1614
|
+ sandbox_vroot = sandbox.get_virtual_directory()
|
|
1615
|
+ collectvdir = sandbox_vroot.descend(collect.lstrip(os.sep).split(os.sep))
|
|
1616
|
+ except VirtualDirectoryError:
|
|
1617
|
+ # No collect directory existed
|
|
1618
|
+ collectvdir = None
|
|
1619
|
+
|
|
1620
|
+ # Create artifact directory structure
|
|
1621
|
+ assembledir = os.path.join(rootdir, 'artifact')
|
|
1622
|
+ filesdir = os.path.join(assembledir, 'files')
|
|
1623
|
+ logsdir = os.path.join(assembledir, 'logs')
|
|
1624
|
+ metadir = os.path.join(assembledir, 'meta')
|
|
1625
|
+ buildtreedir = os.path.join(assembledir, 'buildtree')
|
|
1626
|
+ os.mkdir(assembledir)
|
|
1627
|
+ if collect is not None and collectvdir is not None:
|
|
1628
|
+ os.mkdir(filesdir)
|
|
1629
|
+ os.mkdir(logsdir)
|
|
1630
|
+ os.mkdir(metadir)
|
|
1631
|
+ os.mkdir(buildtreedir)
|
|
1632
|
+
|
|
1633
|
+ # Hard link files from collect dir to files directory
|
|
1634
|
+ if collect is not None and collectvdir is not None:
|
|
1635
|
+ collectvdir.export_files(filesdir, can_link=True)
|
|
1636
|
+
|
|
1637
|
+ try:
|
|
1638
|
+ sandbox_vroot = sandbox.get_virtual_directory()
|
|
1639
|
+ sandbox_build_dir = sandbox_vroot.descend(
|
|
1640
|
+ self.get_variable('build-root').lstrip(os.sep).split(os.sep))
|
|
1641
|
+ # Hard link files from build-root dir to buildtreedir directory
|
|
1642
|
+ sandbox_build_dir.export_files(buildtreedir)
|
|
1643
|
+ except VirtualDirectoryError:
|
|
1644
|
+ # Directory could not be found. Pre-virtual
|
|
1645
|
+ # directory behaviour was to continue silently
|
|
1646
|
+ # if the directory could not be found.
|
|
1647
|
+ pass
|
|
1648
|
+
|
|
1649
|
+ # Copy build log
|
|
1650
|
+ log_filename = context.get_log_filename()
|
|
1651
|
+ self._build_log_path = os.path.join(logsdir, 'build.log')
|
|
1652
|
+ if log_filename:
|
|
1653
|
+ shutil.copyfile(log_filename, self._build_log_path)
|
|
1654
|
+
|
|
1655
|
+ # Store public data
|
|
1656
|
+ _yaml.dump(_yaml.node_sanitize(self.__dynamic_public), os.path.join(metadir, 'public.yaml'))
|
|
1657
|
+
|
|
1658
|
+ # Store result
|
|
1659
|
+ build_result_dict = {"success": self.__build_result[0], "description": self.__build_result[1]}
|
|
1660
|
+ if self.__build_result[2] is not None:
|
|
1661
|
+ build_result_dict["detail"] = self.__build_result[2]
|
|
1662
|
+ _yaml.dump(build_result_dict, os.path.join(metadir, 'build-result.yaml'))
|
|
1663
|
+
|
|
1664
|
+ # ensure we have cache keys
|
|
1665
|
+ self._assemble_done()
|
|
1666
|
+
|
|
1667
|
+ # Store keys.yaml
|
|
1668
|
+ _yaml.dump(_yaml.node_sanitize({
|
|
1669
|
+ 'strong': self._get_cache_key(),
|
|
1670
|
+ 'weak': self._get_cache_key(_KeyStrength.WEAK),
|
|
1671
|
+ }), os.path.join(metadir, 'keys.yaml'))
|
|
1672
|
+
|
|
1673
|
+ # Store dependencies.yaml
|
|
1674
|
+ _yaml.dump(_yaml.node_sanitize({
|
|
1675
|
+ e.name: e._get_cache_key() for e in self.dependencies(Scope.BUILD)
|
|
1676
|
+ }), os.path.join(metadir, 'dependencies.yaml'))
|
|
1677
|
+
|
|
1678
|
+ # Store workspaced.yaml
|
|
1679
|
+ _yaml.dump(_yaml.node_sanitize({
|
|
1680
|
+ 'workspaced': True if self._get_workspace() else False
|
|
1681
|
+ }), os.path.join(metadir, 'workspaced.yaml'))
|
|
1682
|
+
|
|
1683
|
+ # Store workspaced-dependencies.yaml
|
|
1684
|
+ _yaml.dump(_yaml.node_sanitize({
|
|
1685
|
+ 'workspaced-dependencies': [
|
|
1686
|
+ e.name for e in self.dependencies(Scope.BUILD)
|
|
1687
|
+ if e._get_workspace()
|
|
1688
|
+ ]
|
|
1689
|
+ }), os.path.join(metadir, 'workspaced-dependencies.yaml'))
|
|
1690
|
+
|
|
1691
|
+ with self.timed_activity("Caching artifact"):
|
|
1692
|
+ artifact_size = utils._get_dir_size(assembledir)
|
|
1693
|
+ self.__artifacts.commit(self, assembledir, self.__get_cache_keys_for_commit())
|
|
1694
|
+
|
|
1695
|
+ if collect is not None and collectvdir is None:
|
|
1696
|
+ raise ElementError(
|
|
1697
|
+ "Directory '{}' was not found inside the sandbox, "
|
|
1698
|
+ "unable to collect artifact contents"
|
|
1699
|
+ .format(collect))
|
|
1700
|
+
|
|
1701
|
+ return artifact_size
|
|
1702
|
+
|
1689
|
1703
|
def _get_build_log(self):
|
1690
|
1704
|
return self._build_log_path
|
1691
|
1705
|
|