diff options
61 files changed, 389 insertions, 94 deletions
diff --git a/buildstream/_options/optionarch.py b/buildstream/_options/optionarch.py index 13a691643..1d8509cf2 100644 --- a/buildstream/_options/optionarch.py +++ b/buildstream/_options/optionarch.py @@ -17,7 +17,7 @@ # Authors: # Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> -import os +from .._platform import Platform from .optionenum import OptionEnum @@ -41,8 +41,7 @@ class OptionArch(OptionEnum): super(OptionArch, self).load(node, allow_default_definition=False) def load_default_value(self, node): - _, _, _, _, machine_arch = os.uname() - return machine_arch + return Platform.get_host_arch() def resolve(self): diff --git a/buildstream/_options/optionos.py b/buildstream/_options/optionos.py new file mode 100644 index 000000000..e76cf177c --- /dev/null +++ b/buildstream/_options/optionos.py @@ -0,0 +1,41 @@ + +# +# Copyright (C) 2017 Codethink Limited +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see <http://www.gnu.org/licenses/>. +# +# Authors: +# Raoul Hidalgo Charman <raoul.hidalgocharman@codethink.co.uk> + +import os +from .optionenum import OptionEnum + + +# OptionOS +# +class OptionOS(OptionEnum): + + OPTION_TYPE = 'os' + + def load(self, node): + super(OptionOS, self).load(node, allow_default_definition=False) + + def load_default_value(self, node): + return os.uname()[0] + + def resolve(self): + + # Validate that the default OS reported by uname() is explicitly + # supported by the project, if not overridden by user config or cli. + self.validate(self.value) diff --git a/buildstream/_options/optionpool.py b/buildstream/_options/optionpool.py index 1274586f7..3132af564 100644 --- a/buildstream/_options/optionpool.py +++ b/buildstream/_options/optionpool.py @@ -28,6 +28,7 @@ from .optionenum import OptionEnum from .optionflags import OptionFlags from .optioneltmask import OptionEltMask from .optionarch import OptionArch +from .optionos import OptionOS _OPTION_TYPES = { @@ -36,6 +37,7 @@ _OPTION_TYPES = { OptionFlags.OPTION_TYPE: OptionFlags, OptionEltMask.OPTION_TYPE: OptionEltMask, OptionArch.OPTION_TYPE: OptionArch, + OptionOS.OPTION_TYPE: OptionOS, } diff --git a/buildstream/_platform/linux.py b/buildstream/_platform/linux.py index 33f3966c1..702059a5d 100644 --- a/buildstream/_platform/linux.py +++ b/buildstream/_platform/linux.py @@ -25,6 +25,7 @@ from .. import utils from ..sandbox import SandboxDummy from . import Platform +from .._exceptions import PlatformError class Linux(Platform): @@ -58,6 +59,9 @@ class Linux(Platform): else: self._user_ns_available = False + # Set linux32 option + self._linux32 = False + def create_sandbox(self, *args, **kwargs): if not self._local_sandbox_available: return self._create_dummy_sandbox(*args, **kwargs) @@ -71,11 +75,33 @@ class Linux(Platform): if self._user_ns_available: # User namespace support allows arbitrary build UID/GID settings. - return True - else: + pass + elif (config.build_uid != self._uid or config.build_gid != self._gid): # Without user namespace support, the UID/GID in the sandbox # will match the host UID/GID. - return config.build_uid == self._uid and config.build_gid == self._gid + return False + + # We can't do builds for another host or architecture except x86-32 on + # x86-64 + host_os = self.get_host_os() + host_arch = self.get_host_arch() + if config.build_os != host_os: + raise PlatformError("Configured and host OS don't match.") + elif config.build_arch != host_arch: + # We can use linux32 for building 32bit on 64bit machines + if (host_os == "Linux" and + ((config.build_arch == "x86-32" and host_arch == "x86-64") or + (config.build_arch == "aarch32" and host_arch == "aarch64"))): + # check linux32 is available + try: + utils.get_host_tool('linux32') + self._linux32 = True + except utils.ProgramNotFoundError: + pass + else: + raise PlatformError("Configured architecture and host architecture don't match.") + + return True ################################################ # Private Methods # @@ -100,6 +126,7 @@ class Linux(Platform): kwargs['user_ns_available'] = self._user_ns_available kwargs['die_with_parent_available'] = self._die_with_parent_available kwargs['json_status_available'] = self._json_status_available + kwargs['linux32'] = self._linux32 return SandboxBwrap(*args, **kwargs) def _check_user_ns_available(self): diff --git a/buildstream/_platform/platform.py b/buildstream/_platform/platform.py index d3e4b949a..42b360ff8 100644 --- a/buildstream/_platform/platform.py +++ b/buildstream/_platform/platform.py @@ -73,6 +73,44 @@ class Platform(): else: return min(cpu_count, cap) + @staticmethod + def get_host_os(): + return os.uname()[0] + + # get_host_arch(): + # + # This returns the architecture of the host machine. The possible values + # map from uname -m in order to be a OS independent list. + # + # Returns: + # (string): String representing the architecture + @staticmethod + def get_host_arch(): + # get the hardware identifier from uname + uname_machine = os.uname()[4] + uname_to_arch = { + "aarch64": "aarch64", + "aarch64_be": "aarch64-be", + "amd64": "x86-64", + "arm": "aarch32", + "armv8l": "aarch64", + "armv8b": "aarch64-be", + "i386": "x86-32", + "i486": "x86-32", + "i586": "x86-32", + "i686": "x86-32", + "ppc64": "power-isa-be", + "ppc64le": "power-isa-le", + "sparc": "sparc-v9", + "sparc64": "sparc-v9", + "x86_64": "x86-64" + } + try: + return uname_to_arch[uname_machine] + except KeyError: + raise PlatformError("uname gave unsupported machine architecture: {}" + .format(uname_machine)) + ################################################################## # Sandbox functions # ################################################################## diff --git a/buildstream/_platform/unix.py b/buildstream/_platform/unix.py index d2acefe65..bbc55c3af 100644 --- a/buildstream/_platform/unix.py +++ b/buildstream/_platform/unix.py @@ -44,4 +44,13 @@ class Unix(Platform): def check_sandbox_config(self, config): # With the chroot sandbox, the UID/GID in the sandbox # will match the host UID/GID (typically 0/0). - return config.build_uid == self._uid and config.build_gid == self._gid + if config.build_uid != self._uid or config.build_gid != self._gid: + return False + + # Check host os and architecture match + if config.build_os != self.get_host_os(): + raise PlatformError("Configured and host OS don't match.") + elif config.build_arch != self.get_host_arch(): + raise PlatformError("Configured and host architecture don't match.") + + return True diff --git a/buildstream/element.py b/buildstream/element.py index 2f724f49d..27677b054 100644 --- a/buildstream/element.py +++ b/buildstream/element.py @@ -2410,6 +2410,11 @@ class Element(Plugin): project.ensure_fully_loaded() sandbox_config = _yaml.node_chain_copy(project._sandbox) + # Get the platform to ask for host architecture + platform = Platform.get_platform() + host_arch = platform.get_host_arch() + host_os = platform.get_host_os() + # The default config is already composited with the project overrides sandbox_defaults = _yaml.node_get(self.__defaults, Mapping, 'sandbox', default_value={}) sandbox_defaults = _yaml.node_chain_copy(sandbox_defaults) @@ -2419,10 +2424,13 @@ class Element(Plugin): _yaml.node_final_assertions(sandbox_config) # Sandbox config, unlike others, has fixed members so we should validate them - _yaml.node_validate(sandbox_config, ['build-uid', 'build-gid']) + _yaml.node_validate(sandbox_config, ['build-uid', 'build-gid', 'build-os', 'build-arch']) - return SandboxConfig(self.node_get_member(sandbox_config, int, 'build-uid'), - self.node_get_member(sandbox_config, int, 'build-gid')) + return SandboxConfig( + self.node_get_member(sandbox_config, int, 'build-uid'), + self.node_get_member(sandbox_config, int, 'build-gid'), + self.node_get_member(sandbox_config, str, 'build-os', default=host_os), + self.node_get_member(sandbox_config, str, 'build-arch', default=host_arch)) # This makes a special exception for the split rules, which # elements may extend but whos defaults are defined in the project. diff --git a/buildstream/sandbox/_config.py b/buildstream/sandbox/_config.py index 5debe24b2..457f92b3c 100644 --- a/buildstream/sandbox/_config.py +++ b/buildstream/sandbox/_config.py @@ -16,7 +16,6 @@ # # Authors: # Jim MacArthur <jim.macarthur@codethink.co.uk> -import os # SandboxConfig @@ -24,9 +23,11 @@ import os # A container for sandbox configuration data. We want the internals # of this to be opaque, hence putting it in its own private file. class SandboxConfig(): - def __init__(self, build_uid, build_gid): + def __init__(self, build_uid, build_gid, build_os=None, build_arch=None): self.build_uid = build_uid self.build_gid = build_gid + self.build_os = build_os + self.build_arch = build_arch # get_unique_key(): # @@ -45,10 +46,9 @@ class SandboxConfig(): # However this should be the right place to support # such configurations in the future. # - operating_system, _, _, _, machine_arch = os.uname() unique_key = { - 'os': operating_system, - 'arch': machine_arch + 'os': self.build_os, + 'arch': self.build_arch } # Avoid breaking cache key calculation with diff --git a/buildstream/sandbox/_sandboxbwrap.py b/buildstream/sandbox/_sandboxbwrap.py index f7b11326a..d2abc33d0 100644 --- a/buildstream/sandbox/_sandboxbwrap.py +++ b/buildstream/sandbox/_sandboxbwrap.py @@ -57,6 +57,7 @@ class SandboxBwrap(Sandbox): self.user_ns_available = kwargs['user_ns_available'] self.die_with_parent_available = kwargs['die_with_parent_available'] self.json_status_available = kwargs['json_status_available'] + self.linux32 = kwargs['linux32'] def _run(self, command, flags, *, cwd, env): stdout, stderr = self._get_output() @@ -74,8 +75,14 @@ class SandboxBwrap(Sandbox): mount_map = MountMap(self, flags & SandboxFlags.ROOT_READ_ONLY) root_mount_source = mount_map.get_mount_source('/') + # start command with linux32 if needed + if self.linux32: + bwrap_command = [utils.get_host_tool('linux32')] + else: + bwrap_command = [] + # Grab the full path of the bwrap binary - bwrap_command = [utils.get_host_tool('bwrap')] + bwrap_command += [utils.get_host_tool('bwrap')] for k, v in env.items(): bwrap_command += ['--setenv', k, v] diff --git a/buildstream/sandbox/_sandboxremote.py b/buildstream/sandbox/_sandboxremote.py index c366b3f40..a967629fe 100644 --- a/buildstream/sandbox/_sandboxremote.py +++ b/buildstream/sandbox/_sandboxremote.py @@ -126,13 +126,20 @@ class SandboxRemote(Sandbox): EnvironmentVariable(name=k, value=v) for (k, v) in environment.items()] + config = self._get_config() + platform = remote_execution_pb2.Platform() + platform.properties.extend([remote_execution_pb2.Platform. + Property(name="OSFamily", value=config.build_os), + remote_execution_pb2.Platform. + Property(name="ISA", value=config.build_arch)]) + # Create and send the Command object. remote_command = remote_execution_pb2.Command(arguments=command, working_directory=working_directory, environment_variables=environment_variables, output_files=[], output_directories=[self._output_directory], - platform=None) + platform=platform) context = self._get_context() cascache = context.get_cascache() casremote = CASRemote(self.storage_remote_spec) diff --git a/doc/examples/flatpak-autotools/elements/base/sdk.bst b/doc/examples/flatpak-autotools/elements/base/sdk.bst index a1b6c5856..97089b83b 100644 --- a/doc/examples/flatpak-autotools/elements/base/sdk.bst +++ b/doc/examples/flatpak-autotools/elements/base/sdk.bst @@ -5,10 +5,10 @@ sources: url: gnomesdk:repo/ gpg-key: keys/gnome-sdk.gpg (?): - - arch == "x86_64": + - arch == "x86-64": track: runtime/org.freedesktop.BaseSdk/x86_64/1.4 ref: 0d9d255d56b08aeaaffb1c820eef85266eb730cb5667e50681185ccf5cd7c882 - - arch == "i386": + - arch == "x86-32": track: runtime/org.freedesktop.BaseSdk/i386/1.4 ref: 16036b747c1ec8e7fe291f5b1f667cb942f0267d08fcad962e9b7627d6cf1981 config: diff --git a/doc/examples/flatpak-autotools/project.conf b/doc/examples/flatpak-autotools/project.conf index 0296b22f6..401dc561a 100644 --- a/doc/examples/flatpak-autotools/project.conf +++ b/doc/examples/flatpak-autotools/project.conf @@ -10,6 +10,6 @@ options: type: arch description: The machine architecture values: - - x86_64 - - i386 + - x86-64 + - x86-32 diff --git a/doc/source/format_declaring.rst b/doc/source/format_declaring.rst index e1ad4f720..57ea4488a 100644 --- a/doc/source/format_declaring.rst +++ b/doc/source/format_declaring.rst @@ -294,8 +294,10 @@ can be viewed in detail in the :ref:`builtin public data <public_builtin>` secti Sandbox ~~~~~~~ Configuration for the build sandbox (other than :ref:`environment variables <format_environment>`) -can be placed in the ``sandbox`` configuration. At present, only the -UID and GID used by the user in the group can be specified. +can be placed in the ``sandbox`` configuration. The UID and GID used by the user +in the group can be specified, as well as the desired OS and machine +architecture. Possible machine architecture follow the same list as specified in +the :ref:`architecture option <project_options_arch>`. .. code:: yaml @@ -311,6 +313,24 @@ you can supply a different uid or gid for the sandbox. Only bwrap-style sandboxes support custom user IDs at the moment, and hence this will only work on Linux host platforms. +.. code:: yaml + + # Specify build OS and architecture + sandbox: + build-os: AIX + build-arch: power-isa-be + +When building locally, if these don't match the host machine then generally the +build will fail. The exception is when the OS is Linux and the architecture +specifies an ``x86-32`` build on an ``x86-64`` machine, or ``aarch32`` build on +a ``aarch64`` machine, in which case the ``linux32`` command is prepended to the +bubblewrap command. + +When building remotely, the OS and architecture are added to the ``Platform`` +field in the ``Command`` uploaded. Whether this actually results in a building +the element for the desired OS and architecture is dependent on the server +having implemented these options the same as buildstream. + .. note:: The ``sandbox`` configuration is available since :ref:`format version 6 <project_format_version>` diff --git a/doc/source/format_project.rst b/doc/source/format_project.rst index 9b51f8d4b..59ee05e85 100644 --- a/doc/source/format_project.rst +++ b/doc/source/format_project.rst @@ -552,9 +552,22 @@ exported as a comma separated list of selected value strings. Architecture ~~~~~~~~~~~~ -The ``arch`` option type is special enumeration option which -defaults to the result of `uname -m`, and does not support -assigning any default in the project configuration. +The ``arch`` option type is a special enumeration option which defaults via +`uname -m` results to the following list. + +* aarch32 +* aarch64 +* aarch64-be +* power-isa-be +* power-isa-le +* sparc-v9 +* x86-32 +* x86-64 + +The reason for this, opposed to using just `uname -m`, is that we want an +OS-independent list, as well as several results mapping to the same architecture +(e.g. i386, i486 etc. are all x86-32). It does not support assigning any default +in the project configuration. .. code:: yaml @@ -563,16 +576,40 @@ assigning any default in the project configuration. type: arch description: The machine architecture values: - - arm + - aarch32 - aarch64 - - i386 - - x86_64 + - x86-32 + - x86-64 Architecture options can be tested with the same expressions as other Enumeration options. +.. _project_options_os: + +OS +~~ + +The ``os`` option type is a special enumeration option, which defaults to the +results of `uname -s`. It does not support assigning any default in the project +configuration. + +.. code:: yaml + + options: + machine_os: + type: os + description: The machine OS + values: + - Linux + - SunOS + - Darwin + - FreeBSD + +Os options can be tested with the same expressions as other Enumeration options. + + .. _project_options_element_mask: Element mask diff --git a/tests/cachekey/cachekey.py b/tests/cachekey/cachekey.py index 113f5bab0..c278b9ca9 100644 --- a/tests/cachekey/cachekey.py +++ b/tests/cachekey/cachekey.py @@ -144,7 +144,7 @@ DATA_DIR = os.path.join( # The cache key test uses a project which exercises all plugins, # so we cant run it at all if we dont have them installed. # -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', reason='Cache keys depend on architecture') @pytest.mark.skipif(not IS_LINUX, reason='Only available on linux') @pytest.mark.skipif(HAVE_BZR is False, reason="bzr is not available") diff --git a/tests/cachekey/project/elements/build1.expected b/tests/cachekey/project/elements/build1.expected index 27d9595e8..ef18ad98b 100644 --- a/tests/cachekey/project/elements/build1.expected +++ b/tests/cachekey/project/elements/build1.expected @@ -1 +1 @@ -ce0ddf7126d45d14f5ec1a525337c39ec8ddbbe4b0ec2ef51bae777619ed39bb
\ No newline at end of file +a0d000abc1dea8714cd27f348d0b798b35e7246c44e330c4b3f7912fabacc6db
\ No newline at end of file diff --git a/tests/cachekey/project/elements/build2.expected b/tests/cachekey/project/elements/build2.expected index 21328c966..015085d9e 100644 --- a/tests/cachekey/project/elements/build2.expected +++ b/tests/cachekey/project/elements/build2.expected @@ -1 +1 @@ -5e2a48dbeae43f6bab84071dbd02345a3aa32a473c189645ab26f3d5d6cfe547
\ No newline at end of file +79f546a78748d943a6958c99ab4ad03305f96fefd0b424b6b246b0c9816e00c6
\ No newline at end of file diff --git a/tests/cachekey/project/elements/compose1.expected b/tests/cachekey/project/elements/compose1.expected index a76ce029f..2bb7802d7 100644 --- a/tests/cachekey/project/elements/compose1.expected +++ b/tests/cachekey/project/elements/compose1.expected @@ -1 +1 @@ -b63c517f604e8ca64e973476f687190d14a813a0bf77573b93a557f5fb7ae214
\ No newline at end of file +36cb2ac57281343959266e87913eb690f4c68980d7267160ff5f071db778719d
\ No newline at end of file diff --git a/tests/cachekey/project/elements/compose2.expected b/tests/cachekey/project/elements/compose2.expected index cc17908c7..4b03402cb 100644 --- a/tests/cachekey/project/elements/compose2.expected +++ b/tests/cachekey/project/elements/compose2.expected @@ -1 +1 @@ -6676f1cce86166eb66ab83254fe2deb43be93644967de110dd42713dea181508
\ No newline at end of file +30ffe86750a497052f8fc868c47a08644cd579f8e86f59be9b04fa5530b6a9b6
\ No newline at end of file diff --git a/tests/cachekey/project/elements/compose3.expected b/tests/cachekey/project/elements/compose3.expected index cef7e620a..5b975be25 100644 --- a/tests/cachekey/project/elements/compose3.expected +++ b/tests/cachekey/project/elements/compose3.expected @@ -1 +1 @@ -0f8f444566c097067f2dfa54f26100abff85cc49bf9acf0081129f53244bc144
\ No newline at end of file +1bac1d17cc2aed85ab14daf264f955b2204823799bc5bac5ff77c79b32d0c08b
\ No newline at end of file diff --git a/tests/cachekey/project/elements/compose4.expected b/tests/cachekey/project/elements/compose4.expected index 96cb1c4a0..48a96844a 100644 --- a/tests/cachekey/project/elements/compose4.expected +++ b/tests/cachekey/project/elements/compose4.expected @@ -1 +1 @@ -aa72331d42f647e845243e8a77389febfb78acff09f70771a3545bdf0d4d70ad
\ No newline at end of file +99690e3a915f4c5b6f76a5bcee8bffe74d077a4398ac29623be36bca26703290
\ No newline at end of file diff --git a/tests/cachekey/project/elements/compose5.expected b/tests/cachekey/project/elements/compose5.expected index 6fec106a3..40287aa87 100644 --- a/tests/cachekey/project/elements/compose5.expected +++ b/tests/cachekey/project/elements/compose5.expected @@ -1 +1 @@ -37bb4486f42e04b8a1c9f9cb9358adfd0d4dae0bb3b2a4072e090848cd2b955d
\ No newline at end of file +a3e25dabe35a2909920f94c9e457c977b00dfa49c161b82c47ad55e761349c6a
\ No newline at end of file diff --git a/tests/cachekey/project/elements/import1.expected b/tests/cachekey/project/elements/import1.expected index 8e3c582e7..ab07f28da 100644 --- a/tests/cachekey/project/elements/import1.expected +++ b/tests/cachekey/project/elements/import1.expected @@ -1 +1 @@ -ce2dce59ad7fa810c945e7385cc25d4c8992adf71fbdc44336cf136330fe2b16
\ No newline at end of file +791aaae474dce95f98c849d748088697334a9b4bfcb6225c59804efe03e803c9
\ No newline at end of file diff --git a/tests/cachekey/project/elements/import2.expected b/tests/cachekey/project/elements/import2.expected index 5ad1b5816..8b7327e20 100644 --- a/tests/cachekey/project/elements/import2.expected +++ b/tests/cachekey/project/elements/import2.expected @@ -1 +1 @@ -4fd32ee29026ecbcee717c8f04a0b807934a7042d67b8786e0eb9326757c845d
\ No newline at end of file +3aaf0565ffbeb2faa4e48230d07ef839b9bc2ff012780ca9b5f6b9c968f539b2
\ No newline at end of file diff --git a/tests/cachekey/project/elements/import3.expected b/tests/cachekey/project/elements/import3.expected index c5d55728f..05cfbdf2e 100644 --- a/tests/cachekey/project/elements/import3.expected +++ b/tests/cachekey/project/elements/import3.expected @@ -1 +1 @@ -e24dd31bda628616138014391a94040490da0820a2c42ab10ec6dfad1b694df9
\ No newline at end of file +7cadfb9b592af06fa765389278d919cb8e29515ad057710563da9cd1c36e2ce9
\ No newline at end of file diff --git a/tests/cachekey/project/elements/script1.expected b/tests/cachekey/project/elements/script1.expected index 83dbba964..71a53906c 100644 --- a/tests/cachekey/project/elements/script1.expected +++ b/tests/cachekey/project/elements/script1.expected @@ -1 +1 @@ -a139b184c8dd6a6e08231822ca2d886688e5d7720dc2290f8876d485bdb920b5
\ No newline at end of file +14db0665eed7c3d4cf3685c2e386a9e494465927a5ad962c98b92856be3d88b8
\ No newline at end of file diff --git a/tests/cachekey/project/sources/bzr1.expected b/tests/cachekey/project/sources/bzr1.expected index 81bcac7ec..debfe0c9d 100644 --- a/tests/cachekey/project/sources/bzr1.expected +++ b/tests/cachekey/project/sources/bzr1.expected @@ -1 +1 @@ -d2aeb3715c5842461384bea6a9bcf452310d1626ae40b6e7a9f51adc66a270fd
\ No newline at end of file +faadf63e4025e4a068532d01296b65db38dbf2c95625695832f7c601b2134375
\ No newline at end of file diff --git a/tests/cachekey/project/sources/git1.expected b/tests/cachekey/project/sources/git1.expected index dca2d04f0..5a98e679f 100644 --- a/tests/cachekey/project/sources/git1.expected +++ b/tests/cachekey/project/sources/git1.expected @@ -1 +1 @@ -4e03d21335e578034b09191ebf4977f0f537425c3031805dfb2f835ff77925cd
\ No newline at end of file +3dc6b7c47ddb3ced44c42d22f4c192b9245112197172d2f9ce9498e4614bbca4
\ No newline at end of file diff --git a/tests/cachekey/project/sources/git2.expected b/tests/cachekey/project/sources/git2.expected index d32c44557..bfccc82c2 100644 --- a/tests/cachekey/project/sources/git2.expected +++ b/tests/cachekey/project/sources/git2.expected @@ -1 +1 @@ -75c96f6c8d3ca3ffe164cd51f42689287021e60ef524f56340539feadd5a9fb8
\ No newline at end of file +3ded0e77f43c43f86920012d6ffe0e2f0cd98908ceab7023bf5a8d34bedf1d6e
\ No newline at end of file diff --git a/tests/cachekey/project/sources/git3.expected b/tests/cachekey/project/sources/git3.expected index b383ccbfc..c0ab92c20 100644 --- a/tests/cachekey/project/sources/git3.expected +++ b/tests/cachekey/project/sources/git3.expected @@ -1 +1 @@ -6a25f539bd8629a36399c58efd2f5c9c117feb845076a37dc321b55d456932b6
\ No newline at end of file +31e95bdf97eb85d2261c988de7ee055e00c31a76199b495643661e5d1fbd195e
\ No newline at end of file diff --git a/tests/cachekey/project/sources/local1.expected b/tests/cachekey/project/sources/local1.expected index 8e3c582e7..ab07f28da 100644 --- a/tests/cachekey/project/sources/local1.expected +++ b/tests/cachekey/project/sources/local1.expected @@ -1 +1 @@ -ce2dce59ad7fa810c945e7385cc25d4c8992adf71fbdc44336cf136330fe2b16
\ No newline at end of file +791aaae474dce95f98c849d748088697334a9b4bfcb6225c59804efe03e803c9
\ No newline at end of file diff --git a/tests/cachekey/project/sources/local2.expected b/tests/cachekey/project/sources/local2.expected index ffa2c5d51..f59f4a7cf 100644 --- a/tests/cachekey/project/sources/local2.expected +++ b/tests/cachekey/project/sources/local2.expected @@ -1 +1 @@ -de18b7d9ee2358d6924db5a9f72257e2e2a3d5f8450cb8891f8984bfd1101345
\ No newline at end of file +e44b20eaec873dd28471963d789fbb5660eb14754b7711a5ab0d7785d3bffd37
\ No newline at end of file diff --git a/tests/cachekey/project/sources/ostree1.expected b/tests/cachekey/project/sources/ostree1.expected index f12da1ba1..7bfd2ee12 100644 --- a/tests/cachekey/project/sources/ostree1.expected +++ b/tests/cachekey/project/sources/ostree1.expected @@ -1 +1 @@ -b8414e0077057fcac4e10291d88d898d7132dc591e3b265afee1ad59831815ca
\ No newline at end of file +3b13c4a4b3adcfdf2b6bbbc8b74cc8f43cbfd39ec73af1b285bd8fef79a57068
\ No newline at end of file diff --git a/tests/cachekey/project/sources/patch1.expected b/tests/cachekey/project/sources/patch1.expected index b193eca9f..1a2a1a782 100644 --- a/tests/cachekey/project/sources/patch1.expected +++ b/tests/cachekey/project/sources/patch1.expected @@ -1 +1 @@ -a426c94443da29b060af0aed3f2ffdd4470e1ce9cb0592d8696c55a767e448c1
\ No newline at end of file +ffad4c89efdbcabb86aeea338b4d076f9f44dec2b7b0bc0e6ede39a0e792f992
\ No newline at end of file diff --git a/tests/cachekey/project/sources/patch2.expected b/tests/cachekey/project/sources/patch2.expected index 94e975ae2..3a6812987 100644 --- a/tests/cachekey/project/sources/patch2.expected +++ b/tests/cachekey/project/sources/patch2.expected @@ -1 +1 @@ -b884e246b61cc930f33216055e99a82a47dcf42435b860622039555a159fc255
\ No newline at end of file +5e91946c032a83120ae97a84f96dbfbf98992d6decff99df0073a117cd45702e
\ No newline at end of file diff --git a/tests/cachekey/project/sources/patch3.expected b/tests/cachekey/project/sources/patch3.expected index 4e11c37ce..ba20eb320 100644 --- a/tests/cachekey/project/sources/patch3.expected +++ b/tests/cachekey/project/sources/patch3.expected @@ -1 +1 @@ -79e297df970b6faaa1cfd64e5a6b6c8b4611b9128a19a7f22a2ee051174fccc9
\ No newline at end of file +bd55bfb2b546b57ac627ba7756269e5d64cb7a74c990e0ef66c06bd4dc3b44a3
\ No newline at end of file diff --git a/tests/cachekey/project/sources/pip1.expected b/tests/cachekey/project/sources/pip1.expected index 1fe5a50c4..a85714052 100644 --- a/tests/cachekey/project/sources/pip1.expected +++ b/tests/cachekey/project/sources/pip1.expected @@ -1 +1 @@ -d8bdc8848e4d2e3d70a1267e73bf0e63afa778e4c905cad1a94308634176fb87
\ No newline at end of file +09d873158f35ea64e67919373a6cfbd4aaba9321b817c89317b1350da8267318
\ No newline at end of file diff --git a/tests/cachekey/project/sources/remote1.expected b/tests/cachekey/project/sources/remote1.expected index 751816322..2595e6f4c 100644 --- a/tests/cachekey/project/sources/remote1.expected +++ b/tests/cachekey/project/sources/remote1.expected @@ -1 +1 @@ -2ab4d2a2490dabafadfc44d95b78f690105e0f0d1cb58665a6a332920172741e
\ No newline at end of file +fc9d09695a6e04785671cc53e36dbc1dd1391a8bcd4a7003c5cce161f2a6c484
\ No newline at end of file diff --git a/tests/cachekey/project/sources/remote2.expected b/tests/cachekey/project/sources/remote2.expected index 9b0428eb6..1de8e1b76 100644 --- a/tests/cachekey/project/sources/remote2.expected +++ b/tests/cachekey/project/sources/remote2.expected @@ -1 +1 @@ -642cbafb3020ab80dae274a983ade81757cf3a1fa4fbba01f621599830be50fd
\ No newline at end of file +de35773c4cec65912e4cef18682a0fc176a49ee6637b0c5e8f68b546225c0865
\ No newline at end of file diff --git a/tests/cachekey/project/sources/tar1.expected b/tests/cachekey/project/sources/tar1.expected index 64addbfe1..7575b52b3 100644 --- a/tests/cachekey/project/sources/tar1.expected +++ b/tests/cachekey/project/sources/tar1.expected @@ -1 +1 @@ -d32bf753f0507f07c8b660ed8fc4428434faf7d07049de92ee203256db0149a3
\ No newline at end of file +9e2e12cb32b52463fd324afe2f32b622ee76973cdefcb35e0a14c8d0ecf94604
\ No newline at end of file diff --git a/tests/cachekey/project/sources/tar2.expected b/tests/cachekey/project/sources/tar2.expected index 9b4372330..e2e8e36c1 100644 --- a/tests/cachekey/project/sources/tar2.expected +++ b/tests/cachekey/project/sources/tar2.expected @@ -1 +1 @@ -41844c597dbffb4f3dcfaae2e5553836816b1b77744db01e47671ab14276795a
\ No newline at end of file +08b95e17d08ac792e04df9d8165a00ee11520f022895cc6abafe379295a55fc3
\ No newline at end of file diff --git a/tests/cachekey/project/sources/zip1.expected b/tests/cachekey/project/sources/zip1.expected index ac53a32d5..faef2458b 100644 --- a/tests/cachekey/project/sources/zip1.expected +++ b/tests/cachekey/project/sources/zip1.expected @@ -1 +1 @@ -a68328d4ad389a4cdc690103bc6b0bb4d2252eb4f738f6cd004645eb478fcf41
\ No newline at end of file +590963540c16c9c462fbbed88d1c6bf9134e753c652e01710b81d6218bf348bb
\ No newline at end of file diff --git a/tests/cachekey/project/sources/zip2.expected b/tests/cachekey/project/sources/zip2.expected index 3da5f68a7..950b5002f 100644 --- a/tests/cachekey/project/sources/zip2.expected +++ b/tests/cachekey/project/sources/zip2.expected @@ -1 +1 @@ -30c104c539200d568f9157549dd3c8a15a157cb5c56632638b99986e4edf0576
\ No newline at end of file +97dc236aa4f600cfbe6f5d7d47841f547ac6c6ee0e6b55275af8d3f1ec2cb68a
\ No newline at end of file diff --git a/tests/cachekey/project/target.expected b/tests/cachekey/project/target.expected index 0c89af6bb..00ac2beeb 100644 --- a/tests/cachekey/project/target.expected +++ b/tests/cachekey/project/target.expected @@ -1 +1 @@ -bc99c288f855ac2619787f0067223f7812d2e10a9d2c7f2bf47de7113c0fd25c
\ No newline at end of file +d6d283ed1fb0467fcfa5bf69f8596d0f0ac6638281bc9d8e52e1212e2ec0bcab
\ No newline at end of file diff --git a/tests/examples/autotools.py b/tests/examples/autotools.py index e7ca8c5e9..8e4bf5a75 100644 --- a/tests/examples/autotools.py +++ b/tests/examples/autotools.py @@ -13,8 +13,8 @@ DATA_DIR = os.path.join( # Tests a build of the autotools amhello project on a alpine-linux base runtime -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_autotools_build(cli, tmpdir, datafiles): @@ -38,8 +38,8 @@ def test_autotools_build(cli, tmpdir, datafiles): # Test running an executable built with autotools. -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_autotools_run(cli, tmpdir, datafiles): diff --git a/tests/examples/developing.py b/tests/examples/developing.py index 4bb7076c5..0a51802a9 100644 --- a/tests/examples/developing.py +++ b/tests/examples/developing.py @@ -14,8 +14,8 @@ DATA_DIR = os.path.join( # Test that the project builds successfully -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_autotools_build(cli, tmpdir, datafiles): @@ -37,8 +37,8 @@ def test_autotools_build(cli, tmpdir, datafiles): # Test the unmodified hello command works as expected. -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_run_unmodified_hello(cli, tmpdir, datafiles): @@ -70,8 +70,8 @@ def test_open_workspace(cli, tmpdir, datafiles): # Test making a change using the workspace -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_make_change_in_workspace(cli, tmpdir, datafiles): diff --git a/tests/examples/flatpak-autotools.py b/tests/examples/flatpak-autotools.py index dbaf522a2..73910c5eb 100644 --- a/tests/examples/flatpak-autotools.py +++ b/tests/examples/flatpak-autotools.py @@ -32,8 +32,8 @@ def workaround_setuptools_bug(project): # Test that a build upon flatpak runtime 'works' - we use the autotools sample # amhello project for this. -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_OSTREE, reason='Only available on linux with ostree') @pytest.mark.datafiles(DATA_DIR) def test_autotools_build(cli, tmpdir, datafiles): @@ -57,8 +57,8 @@ def test_autotools_build(cli, tmpdir, datafiles): # Test running an executable built with autotools -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_OSTREE, reason='Only available on linux with ostree') @pytest.mark.datafiles(DATA_DIR) def test_autotools_run(cli, tmpdir, datafiles): diff --git a/tests/examples/integration-commands.py b/tests/examples/integration-commands.py index f4b0405e0..71e383008 100644 --- a/tests/examples/integration-commands.py +++ b/tests/examples/integration-commands.py @@ -12,8 +12,8 @@ DATA_DIR = os.path.join( ) -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_integration_commands_build(cli, tmpdir, datafiles): @@ -25,8 +25,8 @@ def test_integration_commands_build(cli, tmpdir, datafiles): # Test running the executable -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_integration_commands_run(cli, tmpdir, datafiles): diff --git a/tests/examples/junctions.py b/tests/examples/junctions.py index 97c622bbd..753fa2dc0 100644 --- a/tests/examples/junctions.py +++ b/tests/examples/junctions.py @@ -13,8 +13,8 @@ DATA_DIR = os.path.join( # Test that the project builds successfully -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_build(cli, tmpdir, datafiles): @@ -25,8 +25,8 @@ def test_build(cli, tmpdir, datafiles): # Test the callHello script works as expected. -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_shell_call_hello(cli, tmpdir, datafiles): diff --git a/tests/examples/running-commands.py b/tests/examples/running-commands.py index 3e679f9c2..61e23fd9c 100644 --- a/tests/examples/running-commands.py +++ b/tests/examples/running-commands.py @@ -12,8 +12,8 @@ DATA_DIR = os.path.join( ) -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_running_commands_build(cli, tmpdir, datafiles): @@ -25,8 +25,8 @@ def test_running_commands_build(cli, tmpdir, datafiles): # Test running the executable -@pytest.mark.skipif(MACHINE_ARCH != 'x86_64', - reason='Examples are writtent for x86_64') +@pytest.mark.skipif(MACHINE_ARCH != 'x86-64', + reason='Examples are writtent for x86-64') @pytest.mark.skipif(not IS_LINUX or not HAVE_BWRAP, reason='Only available on linux with bubblewrap') @pytest.mark.datafiles(DATA_DIR) def test_running_commands_run(cli, tmpdir, datafiles): diff --git a/tests/format/list-directive-type-error/project.conf b/tests/format/list-directive-type-error/project.conf index 1dd0f1b0a..79f73402b 100644 --- a/tests/format/list-directive-type-error/project.conf +++ b/tests/format/list-directive-type-error/project.conf @@ -4,4 +4,4 @@ options: arch: type: arch description: Example architecture option - values: [ x86_32, x86_64, aarch64 ] + values: [ x86-32, x86-64, aarch64 ]
\ No newline at end of file diff --git a/tests/format/option-arch/element.bst b/tests/format/option-arch/element.bst index 4da01d889..2528d9170 100644 --- a/tests/format/option-arch/element.bst +++ b/tests/format/option-arch/element.bst @@ -2,7 +2,7 @@ kind: autotools variables: result: "Nothing" (?): - - machine_arch == "arm": + - machine_arch == "aarch32": result: "Army" - machine_arch == "aarch64": result: "Aarchy" diff --git a/tests/format/option-arch/project.conf b/tests/format/option-arch/project.conf index a2c3ddf9a..8b94232cf 100644 --- a/tests/format/option-arch/project.conf +++ b/tests/format/option-arch/project.conf @@ -5,5 +5,5 @@ options: type: arch description: The machine architecture values: - - arm + - aarch32 - aarch64 diff --git a/tests/format/option-os/element.bst b/tests/format/option-os/element.bst new file mode 100644 index 000000000..8208d67e8 --- /dev/null +++ b/tests/format/option-os/element.bst @@ -0,0 +1,12 @@ +kind: autotools +variables: + result: "Nothing" + (?): + - machine_os == "Linux": + result: "Linuxy" + - machine_os == "Darwin": + result: "Darwiny" + - machine_os == "SunOS": + result: "SunOSy" + - machine_os == "FreeBSD": + result: "FreeBSDy"
\ No newline at end of file diff --git a/tests/format/option-os/project.conf b/tests/format/option-os/project.conf new file mode 100644 index 000000000..5edb5072f --- /dev/null +++ b/tests/format/option-os/project.conf @@ -0,0 +1,11 @@ +name: test + +options: + machine_os: + type: os + description: The operating system + values: + - Linux + - Darwin + - FreeBSD + - SunOS diff --git a/tests/format/optionarch.py b/tests/format/optionarch.py index 4c126aa87..901b6e2da 100644 --- a/tests/format/optionarch.py +++ b/tests/format/optionarch.py @@ -29,7 +29,7 @@ def override_uname_arch(name): @pytest.mark.datafiles(DATA_DIR) @pytest.mark.parametrize("uname,value,expected", [ # Test explicitly provided arches - ('arm', 'arm', 'Army'), + ('arm', 'aarch32', 'Army'), ('arm', 'aarch64', 'Aarchy'), # Test automatically derived arches @@ -38,7 +38,7 @@ def override_uname_arch(name): # Test that explicitly provided arches dont error out # when the `uname` reported arch is not supported - ('i386', 'arm', 'Army'), + ('i386', 'aarch32', 'Army'), ('x86_64', 'aarch64', 'Aarchy'), ]) def test_conditional(cli, datafiles, uname, value, expected): diff --git a/tests/format/optionos.py b/tests/format/optionos.py new file mode 100644 index 000000000..b05d7e49e --- /dev/null +++ b/tests/format/optionos.py @@ -0,0 +1,76 @@ +import os +import pytest +from contextlib import contextmanager + +from buildstream import _yaml +from buildstream._exceptions import ErrorDomain, LoadErrorReason +from tests.testutils.runcli import cli + +DATA_DIR = os.path.dirname(os.path.realpath(__file__)) + + +@contextmanager +def override_uname_os(name): + orig_uname = os.uname + orig_tuple = tuple(os.uname()) + override_result = (name, orig_tuple[1], + orig_tuple[2], orig_tuple[3], + orig_tuple[4]) + + def override(): + return override_result + + os.uname = override + yield + os.uname = orig_uname + + +@pytest.mark.datafiles(DATA_DIR) +@pytest.mark.parametrize("uname,value,expected", [ + # Test explicitly provided arches + ('Darwin', 'Linux', 'Linuxy'), + ('SunOS', 'FreeBSD', 'FreeBSDy'), + + # Test automatically derived arches + ('Linux', None, 'Linuxy'), + ('Darwin', None, 'Darwiny'), + + # Test that explicitly provided arches dont error out + # when the `uname` reported arch is not supported + ('AIX', 'Linux', 'Linuxy'), + ('HaikuOS', 'SunOS', 'SunOSy'), +]) +def test_conditionals(cli, datafiles, uname, value, expected): + with override_uname_os(uname): + project = os.path.join(datafiles.dirname, datafiles.basename, 'option-os') + + bst_args = [] + if value is not None: + bst_args += ['--option', 'machine_os', value] + + bst_args += [ + 'show', + '--deps', 'none', + '--format', '%{vars}', + 'element.bst' + ] + result = cli.run(project=project, silent=True, args=bst_args) + result.assert_success() + + loaded = _yaml.load_data(result.output) + assert loaded['result'] == expected + + +@pytest.mark.datafiles(DATA_DIR) +def test_unsupported_arch(cli, datafiles): + + with override_uname_os("AIX"): + project = os.path.join(datafiles.dirname, datafiles.basename, 'option-os') + result = cli.run(project=project, silent=True, args=[ + 'show', + '--deps', 'none', + '--format', '%{vars}', + 'element.bst' + ]) + + result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA) diff --git a/tests/integration/base/generate-base.sh b/tests/integration/base/generate-base.sh index d1ebd58ae..338c6d98f 100755 --- a/tests/integration/base/generate-base.sh +++ b/tests/integration/base/generate-base.sh @@ -9,7 +9,7 @@ set -eux -ALPINE_ARCH=${ARCH:-x86_64} +ALPINE_ARCH=${ARCH:-x86-64} ALPINE_BASE=http://dl-cdn.alpinelinux.org/alpine/v3.7/releases/${ALPINE_ARCH}/alpine-minirootfs-3.7.0-${ALPINE_ARCH}.tar.gz mkdir root diff --git a/tests/integration/project/elements/base/base-alpine.bst b/tests/integration/project/elements/base/base-alpine.bst index dd5ee7d88..c5833095d 100644 --- a/tests/integration/project/elements/base/base-alpine.bst +++ b/tests/integration/project/elements/base/base-alpine.bst @@ -9,7 +9,7 @@ sources: - kind: tar base-dir: '' (?): - - arch == "x86_64": + - arch == "x86-64": ref: 3eb559250ba82b64a68d86d0636a6b127aa5f6d25d3601a79f79214dc9703639 url: "alpine:integration-tests-base.v1.x86_64.tar.xz" - arch == "aarch64": diff --git a/tests/integration/project/project.conf b/tests/integration/project/project.conf index e0475539a..726f65686 100644 --- a/tests/integration/project/project.conf +++ b/tests/integration/project/project.conf @@ -13,7 +13,7 @@ options: type: arch description: Current architecture values: - - x86_64 + - x86-64 - aarch64 split-rules: test: diff --git a/tests/testutils/site.py b/tests/testutils/site.py index 6c286e720..c7625cccf 100644 --- a/tests/testutils/site.py +++ b/tests/testutils/site.py @@ -5,6 +5,7 @@ import os import sys from buildstream import _site, utils, ProgramNotFoundError +from buildstream._platform import Platform try: utils.get_host_tool('bzr') @@ -52,4 +53,4 @@ except ImportError: IS_LINUX = os.getenv('BST_FORCE_BACKEND', sys.platform).startswith('linux') -_, _, _, _, MACHINE_ARCH = os.uname() +MACHINE_ARCH = Platform.get_host_arch() |