Пример #1
0
  def testSafeSymlink(self):
    """Test that we can create symlinks."""
    with osutils.TempDir(sudo_rm=True) as tempdir:
      file_a = os.path.join(tempdir, 'a')
      osutils.WriteFile(file_a, 'a')

      file_b = os.path.join(tempdir, 'b')
      osutils.WriteFile(file_b, 'b')

      user_dir = os.path.join(tempdir, 'bar')
      user_link = os.path.join(user_dir, 'link')
      osutils.SafeMakedirs(user_dir)

      root_dir = os.path.join(tempdir, 'foo')
      root_link = os.path.join(root_dir, 'link')
      osutils.SafeMakedirs(root_dir, sudo=True)

      # We can create and override links owned by a non-root user.
      osutils.SafeSymlink(file_a, user_link)
      self.assertEqual('a', osutils.ReadFile(user_link))

      osutils.SafeSymlink(file_b, user_link)
      self.assertEqual('b', osutils.ReadFile(user_link))

      # We can create and override links owned by root.
      osutils.SafeSymlink(file_a, root_link, sudo=True)
      self.assertEqual('a', osutils.ReadFile(root_link))

      osutils.SafeSymlink(file_b, root_link, sudo=True)
      self.assertEqual('b', osutils.ReadFile(root_link))
Пример #2
0
    def _GenerateProfile(self):
        """Generates the portage profile for this sysroot.

    The generated portage profile depends on the profiles of all used bricks in
    order as well as the general brillo profile for this architecture.
    """
        overlays = self.GetStandardField(
            STANDARD_FIELD_BOARD_OVERLAY).splitlines()
        profile_list = [os.path.join(o, 'profiles', 'base') for o in overlays]

        # Keep only the profiles that exist.
        profile_list = [p for p in profile_list if os.path.exists(p)]

        # Add the arch specific profile.
        # The profile list is ordered from the lowest to the highest priority. This
        # profile has to go first so that other profiles can override it.
        arch = self.GetStandardField(STANDARD_FIELD_ARCH)
        profile_list.insert(0, 'chromiumos:default/linux/%s/brillo' % arch)

        generated_parent = os.path.join(self.path, 'build',
                                        'generated_profile', 'parent')
        osutils.WriteFile(generated_parent,
                          '\n'.join(profile_list),
                          sudo=True,
                          makedirs=True)
        profile_link = os.path.join(self.path, 'etc', 'portage',
                                    'make.profile')
        osutils.SafeMakedirs(os.path.dirname(profile_link), sudo=True)
        osutils.SafeSymlink(os.path.dirname(generated_parent),
                            profile_link,
                            sudo=True)
Пример #3
0
  def setUp(self):
    self.file_path = os.path.join(self.tempdir, 'file')
    self.dir_path = os.path.join(self.tempdir, 'directory')
    osutils.Touch(self.file_path)
    osutils.SafeMakedirs(self.dir_path)

    os.chdir(self.tempdir)
    osutils.SafeSymlink(self.file_path, 'abs_file_symlink')
    osutils.SafeSymlink('./file', 'rel_file_symlink')
    osutils.SafeSymlink(self.dir_path, 'abs_dir_symlink')
    osutils.SafeSymlink('./directory', 'rel_dir_symlink')

    self.abs_file_symlink = os.path.join(self.tempdir, 'abs_file_symlink')
    self.rel_file_symlink = os.path.join(self.tempdir, 'rel_file_symlink')
    self.abs_dir_symlink = os.path.join(self.tempdir, 'abs_dir_symlink')
    self.rel_dir_symlink = os.path.join(self.tempdir, 'rel_dir_symlink')
Пример #4
0
    def CreateAllWrappers(self, friendly_name=None):
        """Creates all the wrappers.

    Creates all portage tools wrappers, plus wrappers for gdb, cros_workon and
    pkg-config.

    Args:
      friendly_name: if not None, create friendly wrappers with |friendly_name|
        added to the command.
    """
        chost = self.GetStandardField(STANDARD_FIELD_CHOST)
        for cmd in ('ebuild', 'eclean', 'emaint', 'equery', 'portageq',
                    'qcheck', 'qdepends', 'qfile', 'qlist', 'qmerge', 'qsize'):
            args = {'sysroot': self.path, 'chost': chost, 'command': cmd}
            if friendly_name:
                _CreateWrapper(self._WrapperPath(cmd, friendly_name),
                               _PORTAGE_WRAPPER_TEMPLATE, **args)
            _CreateWrapper(self._WrapperPath(cmd), _PORTAGE_WRAPPER_TEMPLATE,
                           **args)

        if friendly_name:
            _CreateWrapper(self._WrapperPath('emerge', friendly_name),
                           _PORTAGE_WRAPPER_TEMPLATE,
                           sysroot=self.path,
                           chost=chost,
                           command='emerge --root-deps',
                           source_root=constants.SOURCE_ROOT)

            _CreateWrapper(self._WrapperPath('cros_workon', friendly_name),
                           _BOARD_WRAPPER_TEMPLATE,
                           board=friendly_name,
                           command='cros_workon')
            _CreateWrapper(self._WrapperPath('gdb', friendly_name),
                           _BOARD_WRAPPER_TEMPLATE,
                           board=friendly_name,
                           command='cros_gdb')
            _CreateWrapper(self._WrapperPath('pkg-config', friendly_name),
                           _PKGCONFIG_WRAPPER_TEMPLATE,
                           sysroot=self.path)

        _CreateWrapper(self._WrapperPath('pkg-config'),
                       _PKGCONFIG_WRAPPER_TEMPLATE,
                       sysroot=self.path)
        _CreateWrapper(self._WrapperPath('emerge'),
                       _PORTAGE_WRAPPER_TEMPLATE,
                       sysroot=self.path,
                       chost=chost,
                       command='emerge --root-deps',
                       source_root=constants.SOURCE_ROOT)

        # Create a link to the debug symbols in the chroot so that gdb can detect
        # them.
        debug_symlink = os.path.join('/usr/lib/debug', self.path.lstrip('/'))
        sysroot_debug = os.path.join(self.path, 'usr/lib/debug')
        osutils.SafeMakedirs(os.path.dirname(debug_symlink), sudo=True)
        osutils.SafeMakedirs(sysroot_debug, sudo=True)

        osutils.SafeSymlink(sysroot_debug, debug_symlink, sudo=True)
Пример #5
0
    def _SelectDefaultMakeConf(self):
        """Selects the best make.conf file possible.

    The best make.conf possible is the ARCH-specific make.conf. If it does not
    exist, we use the generic make.conf.
    """
        make_conf = os.path.join(constants.SOURCE_ROOT,
                                 constants.CHROMIUMOS_OVERLAY_DIR, 'chromeos',
                                 'config', 'make.conf.generic-target')
        link = os.path.join(self.path, 'etc', 'make.conf')
        osutils.SafeSymlink(make_conf, link, sudo=True)
Пример #6
0
    def InstallMakeConfUser(self):
        """Make sure the sysroot has the make.conf.user file.

    This method assumes the chroot's make.conf.user file exists.
    See chroot_util.CreateMakeConfUser() to create one if needed.
    Only works inside the chroot.
    """
        make_user = _GetChrootMakeConfUserPath()
        link_path = self._Path(_MAKE_CONF_USER)
        if not os.path.exists(link_path):
            osutils.SafeSymlink(make_user, link_path, sudo=True)
Пример #7
0
    def CreateSkeleton(self):
        """Creates a sysroot skeleton."""
        needed_dirs = [
            os.path.join(self.path, 'etc', 'portage', 'hooks'),
            os.path.join(self.path, 'etc'),
            os.path.join(self.path, 'etc', 'portage', 'profile'),
            os.path.join('/', 'usr', 'local', 'bin'),
        ]
        for d in needed_dirs:
            osutils.SafeMakedirs(d, sudo=True)

        make_user = os.path.join('/', 'etc', 'make.conf.user')
        link = os.path.join(self.path, 'etc', 'make.conf.user')
        if not os.path.exists(make_user):
            osutils.WriteFile(make_user, '', sudo=True)
        osutils.SafeSymlink(make_user, link, sudo=True)

        # Create links for portage hooks.
        hook_glob = os.path.join(constants.CROSUTILS_DIR, 'hooks', '*')
        for filename in glob.glob(hook_glob):
            linkpath = os.path.join(self.path, 'etc', 'portage', 'hooks',
                                    os.path.basename(filename))
            osutils.SafeSymlink(filename, linkpath, sudo=True)
Пример #8
0
    def CreateSkeleton(self):
        """Creates a sysroot skeleton."""
        needed_dirs = [
            self._Path('etc', 'portage', 'hooks'),
            self._Path('etc', 'portage', 'profile'),
            '/usr/local/bin',
        ]
        for d in needed_dirs:
            osutils.SafeMakedirs(d, sudo=True)

        # Create links for portage hooks.
        hook_glob = os.path.join(constants.CROSUTILS_DIR, 'hooks', '*')
        for filename in glob.glob(hook_glob):
            linkpath = self._Path('etc', 'portage', 'hooks',
                                  os.path.basename(filename))
            osutils.SafeSymlink(filename, linkpath, sudo=True)
def ChooseProfile(board, profile):
    """Make the link to choose the profile, print relevant warnings.

  Args:
    board: Board - the board being used.
    profile: Profile - the profile being used.

  Raises:
    OSError when the board's make_profile path exists and is not a link.
  """
    if not os.path.isfile(os.path.join(profile.directory, 'parent')):
        logging.warning(
            "Portage profile directory %s has no 'parent' file. "
            'This likely means your profile directory is invalid and '
            'build_packages will fail.', profile.directory)

    current_profile = None
    if os.path.exists(board.make_profile):
        # Only try to read if it exists; we only want it to raise an error when the
        # path exists and is not a link.
        try:
            current_profile = os.readlink(board.make_profile)
        except OSError:
            raise MakeProfileIsNotLinkError('%s is not a link.' %
                                            board.make_profile)

    if current_profile == profile.directory:
        # The existing link is what we were going to make, so nothing to do.
        return
    elif current_profile is not None:
        # It exists and is changing, emit warning.
        fmt = {'board': board.board_variant, 'profile': profile.name}
        msg = (
            'You are switching profiles for a board that is already setup. This '
            'can cause trouble for Portage. If you experience problems with '
            'build_packages you may need to run:\n'
            "\t'setup_board --board %(board)s --force --profile %(profile)s'\n"
            '\nAlternatively, you can correct the dependency graph by using '
            "'emerge-%(board)s -c' or 'emerge-%(board)s -C <ebuild>'.")
        logging.warning(msg, fmt)

    # Make the symlink, overwrites existing link if one already exists.
    osutils.SafeSymlink(profile.directory, board.make_profile, sudo=True)

    # Update the profile override value.
    if profile.override:
        board.profile_override = profile.override
Пример #10
0
  def _RefreshSymlinks(self):
    """Recreates the symlinks.

    This will create the three symlinks needed:
    * package.mask/cros-workon: list of packages to mask.
    * package.unmask/cros-workon: list of packages to unmask.
    * package.keywords/cros-workon: list of hidden packages to accept.
    """
    for target, symlink in ((self.masked_file_path, self._masked_symlink),
                            (self.workon_file_path, self._unmasked_symlink),
                            (self.workon_file_path, self._keywords_symlink)):
      if os.path.exists(target):
        osutils.SafeMakedirs(os.path.dirname(symlink), sudo=True)
        osutils.SafeSymlink(target, symlink, sudo=True)
      else:
        logging.debug("Symlink %s already exists. Don't recreated it."
                      % symlink)
Пример #11
0
  def _Mount(self, part, mount_opts):
    if not self.destination:
      self.destination = osutils.TempDir().tempdir
      self._destination_created = True

    dest_number, dest_label = self._GetMountPointAndSymlink(part)
    if part in self._mounted and 'remount' not in mount_opts:
      return dest_number

    osutils.MountDir(self.GetPartitionDevName(part.number), dest_number,
                     makedirs=True, skip_mtab=False, sudo=True,
                     mount_opts=mount_opts)
    self._mounted.add(part)

    osutils.SafeSymlink(os.path.basename(dest_number), dest_label)
    self._symlinks.add(dest_label)

    return dest_number
    def __init__(self, path, profile, overlays):
        self.path = path

        osutils.SafeMakedirs(path / 'etc' / 'portage' / 'profile')
        osutils.SafeMakedirs(path / 'etc' / 'portage' / 'hooks')

        osutils.SafeSymlink(profile.full_path,
                            path / 'etc' / 'portage' / 'make.profile')

        sysroot_conf = {
            'ACCEPT_KEYWORDS':
            'amd64',
            'ROOT':
            str(self.path),
            'SYSROOT':
            str(self.path),
            'ARCH':
            'amd64',
            'PORTAGE_CONFIGROOT':
            str(self.path),
            'PORTDIR':
            str(overlays[0].path),
            'PORTDIR_OVERLAY':
            '\n'.join(
                itertools.chain((str(o.path) for o in overlays),
                                Sysroot._BOOTSTRAP_PORTDIR_OVERLAYS)),
            'PORTAGE_BINHOST':
            '',
            'USE':
            '',
            'PKGDIR':
            str(self.path / 'packages'),
            'PORTAGE_TMPDIR':
            str(self.path / 'tmp'),
            'DISTDIR':
            str(self.path / 'var' / 'lib' / 'portage' / 'distfiles'),
        }

        osutils.WriteFile(self.path / 'etc' / 'portage' / 'make.conf',
                          _dict_to_ebuild(sysroot_conf))

        osutils.WriteFile(self.path / 'etc' / 'portage' / 'package.mask',
                          ''.join(f'*/*::{o}\n' for o in _EXCLUDED_OVERLAYS))
Пример #13
0
    def Install(self):
        """Installs (sets up) an LLVM binary in the sysroot.

    Sets up an llvm binary in the sysroot so that it can be run there.
    """
        # Create a directory for installing |binary| and all of its dependencies in
        # the sysroot.
        binary_rel_path = ['usr', 'bin', self.binary]
        binary_chroot_path = os.path.join('/', *binary_rel_path)
        if not os.path.exists(binary_chroot_path):
            logging.warning('Cannot copy %s, file does not exist in chroot.',
                            binary_chroot_path)
            logging.warning('Functionality provided by %s will be missing.',
                            binary_chroot_path)
            return

        osutils.SafeMakedirsNonRoot(self.install_dir)

        # Copy the binary and everything needed to run it into the sysroot.
        cmd = [
            self.LDDTREE_SCRIPT_PATH,
            '-v',
            '--generate-wrappers',
            '--root',
            '/',
            '--copy-to-tree',
            self.install_dir,
            binary_chroot_path,
        ]
        sudo_run(cmd)

        # Create a symlink to the copy of the binary (we can't do lddtree in
        # self.binary_dir_path). Note that symlink should be relative so that it
        # will be valid when chrooted into the sysroot.
        rel_path = os.path.relpath(self.install_dir, self.binary_dir_path)
        link_path = os.path.join(rel_path, *binary_rel_path)
        osutils.SafeSymlink(link_path, self.binary_chroot_dest_path, sudo=True)
Пример #14
0
 def InstallMakeConf(self):
     """Make sure the make.conf file exists and is up to date."""
     config_file = _GetMakeConfGenericPath()
     osutils.SafeSymlink(config_file, self._Path(_MAKE_CONF), sudo=True)
Пример #15
0
    def setUp(self):
        """Setup filesystem for the profile tests."""
        # Make sure everything will use the filesystem we're setting up.
        cros_choose_profile.PathPrefixDecorator.prefix = self.tempdir

        D = cros_test_lib.Directory
        filesystem = (
            D('board1-overlay', (D('profiles', (
                D('base', ('parent', )),
                D('profile1', ('parent', )),
                D('profile2', ('parent', )),
            )), )),
            D(
                'build',
                (
                    D(
                        'board1',
                        (
                            D(
                                'etc',
                                (
                                    D('portage',
                                      ()),  # make.profile parent directory.
                                    'make.conf.board_setup',
                                )),
                            D('var', (D('cache', (D('edb',
                                                    ('chromeos', )), )), )),
                        )), )),
        )

        cros_test_lib.CreateOnDiskHierarchy(self.tempdir, filesystem)

        # Generate the required filesystem content.
        # Build out the file names that need content.
        b1_build_root = '/build/board1'
        b1_board_setup = os.path.join(b1_build_root,
                                      'etc/make.conf.board_setup')
        self.b1_sysroot = os.path.join(b1_build_root, 'var/cache/edb/chromeos')
        b1_profiles = '/board1-overlay/profiles'

        base_directory = os.path.join(b1_profiles, 'base')
        base_parent = os.path.join(base_directory, 'parent')
        p1_directory = os.path.join(b1_profiles, 'profile1')
        p1_parent = os.path.join(p1_directory, 'parent')
        p2_directory = os.path.join(b1_profiles, 'profile2')
        p2_parent = os.path.join(p2_directory, 'parent')

        # Contents to write to the corresponding file.

        # self.profile_override is assumed to be a profile name in testGetProfile.
        # Update code there if this changes.
        self.profile_override = 'profile1'
        path_contents = {
            b1_board_setup: 'ARCH="arch"\nBOARD_OVERLAY="/board1-overlay"',
            self.b1_sysroot: 'PROFILE_OVERRIDE="%s"' % self.profile_override,
            base_parent: 'base parent contents',
            p1_parent: 'profile1 parent contents',
            p2_parent: 'profile2 parent contents',
        }

        for filepath, contents in path_contents.items():
            osutils.WriteFile(self._TempdirPath(filepath), contents)

        # Mapping between profile argument and the expected parent contents.
        self.profile_expected_parent = {
            'base': path_contents[base_parent],
            'profile1': path_contents[p1_parent],
            'profile2': path_contents[p2_parent],
        }

        # Mapping between the profile argument and the profile's directory.
        self.profile_directory = {
            'base': base_directory,
            'profile1': p1_directory,
            'profile2': p2_directory,
        }

        # The make profile directory from which parent files are read.
        self.board1_make_profile = '/build/board1/etc/portage/make.profile'

        self.board1 = cros_choose_profile.Board(board_root=b1_build_root)

        osutils.SafeSymlink(self._TempdirPath(p1_directory),
                            self._TempdirPath(self.board1_make_profile))