| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Module containing SDK stages.""" |
| |
| from __future__ import print_function |
| |
| import json |
| import os |
| |
| from chromite.cbuildbot import constants |
| from chromite.cbuildbot.stages import generic_stages |
| from chromite.lib import cros_build_lib |
| from chromite.lib import git |
| from chromite.lib import osutils |
| from chromite.lib import portage_util |
| |
| |
| class SDKPackageStage(generic_stages.BuilderStage): |
| """Stage that performs preparing and packaging SDK files""" |
| |
| # Version of the Manifest file being generated. Should be incremented for |
| # Major format changes. |
| MANIFEST_VERSION = '1' |
| _EXCLUDED_PATHS = ('usr/lib/debug', constants.AUTOTEST_BUILD_PATH, |
| 'packages', 'tmp') |
| |
| def PerformStage(self): |
| tarball_name = 'built-sdk.tar.xz' |
| tarball_location = os.path.join(self._build_root, tarball_name) |
| chroot_location = os.path.join(self._build_root, |
| constants.DEFAULT_CHROOT_DIR) |
| board_location = os.path.join(chroot_location, 'build/amd64-host') |
| manifest_location = os.path.join(self._build_root, |
| '%s.Manifest' % tarball_name) |
| |
| # Create a tarball of the latest SDK. |
| self.CreateSDKTarball(chroot_location, board_location, tarball_location) |
| |
| # Create a package manifest for the tarball. |
| self.CreateManifestFromSDK(board_location, manifest_location) |
| |
| # Create toolchain packages. |
| self.CreateRedistributableToolchains(chroot_location) |
| |
| # Make sure the regular user has the permission to read. |
| cmd = ['chmod', 'a+r', tarball_location] |
| cros_build_lib.SudoRunCommand(cmd, cwd=board_location) |
| |
| def CreateRedistributableToolchains(self, chroot_location): |
| """Create the toolchain packages""" |
| osutils.RmDir(os.path.join(chroot_location, |
| constants.SDK_TOOLCHAINS_OUTPUT), |
| ignore_missing=True) |
| |
| # We need to run this as root because the tool creates hard links to root |
| # owned files and our bots enable security features which disallow that. |
| # Specifically, these features cause problems: |
| # /proc/sys/kernel/yama/protected_nonaccess_hardlinks |
| # /proc/sys/fs/protected_hardlinks |
| cmd = [ |
| git.ReinterpretPathForChroot(os.path.join( |
| constants.CHROMITE_BIN_DIR, 'cros_setup_toolchains')), |
| '--create-packages', |
| '--output-dir', os.path.join('/', constants.SDK_TOOLCHAINS_OUTPUT), |
| ] |
| cros_build_lib.SudoRunCommand(cmd, enter_chroot=True) |
| |
| def CreateSDKTarball(self, _chroot, sdk_path, dest_tarball): |
| """Creates an SDK tarball from a given source chroot. |
| |
| Args: |
| chroot: A chroot used for finding compression tool. |
| sdk_path: Path to the root of newly generated SDK image. |
| dest_tarball: Path of the tarball that should be created. |
| """ |
| # TODO(zbehan): We cannot use xz from the chroot unless it's |
| # statically linked. |
| extra_args = ['--exclude=%s/*' % path for path in self._EXCLUDED_PATHS] |
| # Options for maximum compression. |
| extra_env = { 'XZ_OPT' : '-e9' } |
| cros_build_lib.CreateTarball( |
| dest_tarball, sdk_path, sudo=True, extra_args=extra_args, |
| extra_env=extra_env) |
| |
| def CreateManifestFromSDK(self, sdk_path, dest_manifest): |
| """Creates a manifest from a given source chroot. |
| |
| Args: |
| sdk_path: Path to the root of the SDK to describe. |
| dest_manifest: Path to the manifest that should be generated. |
| """ |
| package_data = {} |
| for key, version in portage_util.ListInstalledPackages(sdk_path): |
| package_data.setdefault(key, []).append((version, {})) |
| self._WriteManifest(package_data, dest_manifest) |
| |
| def _WriteManifest(self, data, manifest): |
| """Encode manifest into a json file.""" |
| json_input = dict(version=self.MANIFEST_VERSION, packages=data) |
| osutils.WriteFile(manifest, json.dumps(json_input)) |
| |
| |
| class SDKTestStage(generic_stages.BuilderStage): |
| """Stage that performs testing an SDK created in a previous stage""" |
| |
| option_name = 'tests' |
| |
| def PerformStage(self): |
| tarball_location = os.path.join(self._build_root, 'built-sdk.tar.xz') |
| new_chroot_cmd = ['cros_sdk', '--chroot', 'new-sdk-chroot'] |
| # Build a new SDK using the provided tarball. |
| cmd = new_chroot_cmd + ['--download', '--replace', '--nousepkg', |
| '--url', 'file://' + tarball_location] |
| cros_build_lib.RunCommand(cmd, cwd=self._build_root, |
| extra_env=self._portage_extra_env) |
| |
| for board in self._boards: |
| cros_build_lib.PrintBuildbotStepText(board) |
| cmd = new_chroot_cmd + ['--', './setup_board', |
| '--board', board, '--skip_chroot_upgrade'] |
| cros_build_lib.RunCommand(cmd, cwd=self._build_root) |
| cmd = new_chroot_cmd + ['--', './build_packages', |
| '--board', board, '--nousepkg', '--skip_chroot_upgrade'] |
| cros_build_lib.RunCommand(cmd, cwd=self._build_root, |
| extra_env=self._portage_extra_env) |