def testMountFailFallback(self): """Test that mount failure with overlay fs_type fallsback to overlayfs.""" def _FailOverlay(*_args, **kwargs): if kwargs['fs_type'] == 'overlay': raise cros_build_lib.RunCommandError( 'Phony failure', cros_build_lib.CommandResult(cmd='MounDir', returncode=32)) mount_call = self.PatchObject(osutils, 'MountDir') mount_call.side_effect = _FailOverlay umount_call = self.PatchObject(osutils, 'UmountDir') for cleanup in (True, False): with osutils.MountOverlayContext(self.lowerdir, self.upperdir, self.mergeddir, cleanup=cleanup): mount_call.assert_any_call( 'overlay', self.mergeddir, fs_type='overlay', makedirs=False, mount_opts=('lowerdir=%s' % self.lowerdir, 'upperdir=%s' % self.upperdir, mock.ANY), quiet=mock.ANY) mount_call.assert_any_call( 'overlayfs', self.mergeddir, fs_type='overlayfs', makedirs=False, mount_opts=('lowerdir=%s' % self.lowerdir, 'upperdir=%s' % self.upperdir), quiet=mock.ANY) umount_call.assert_any_call(self.mergeddir, cleanup=cleanup)
def PerformStage(self): chroot_dir = os.path.join(self._build_root, constants.DEFAULT_CHROOT_DIR) sdk_dir = os.path.join(chroot_dir, 'build/amd64-host') tmp_dir = os.path.join(chroot_dir, 'tmp') osutils.SafeMakedirs(tmp_dir, mode=0o777, sudo=True) overlay_output_dir = os.path.join(chroot_dir, constants.SDK_OVERLAYS_OUTPUT) osutils.RmDir(overlay_output_dir, ignore_missing=True, sudo=True) osutils.SafeMakedirs(overlay_output_dir, mode=0o777, sudo=True) overlay_tarball_template = os.path.join( overlay_output_dir, TOOLCHAINS_OVERLAY_TARBALL_TEMPLATE) # Generate an overlay tarball for each unique toolchain combination. We # restrict ourselves to (a) board configs that are available to the builder # (naturally), and (b) toolchains that are part of the 'sdk' set. sdk_toolchains = set(toolchain.GetToolchainsForBoard('sdk')) generated = set() for board in self._run.site_config.GetBoards(): try: toolchains = set(toolchain.GetToolchainsForBoard(board).iterkeys()) except portage_util.MissingOverlayException: # The board overlay may not exist, e.g. on external builders. continue toolchains_str = '-'.join(sorted(toolchains)) if not toolchains.issubset(sdk_toolchains) or toolchains_str in generated: continue with osutils.TempDir(prefix='toolchains-overlay-%s.' % toolchains_str, base_dir=tmp_dir, sudo_rm=True) as overlay_dir: # NOTE: We let MountOverlayContext remove the mount point created by # the TempDir context below, because it has built-in retries for rmdir # EBUSY errors that are due to unmount lag. with osutils.TempDir(prefix='amd64-host-%s.' % toolchains_str, base_dir=tmp_dir, delete=False) as merged_dir: with osutils.MountOverlayContext(sdk_dir, overlay_dir, merged_dir, cleanup=True): sysroot = merged_dir[len(chroot_dir):] cmd = ['cros_setup_toolchains', '--targets=boards', '--include-boards=%s' % board, '--sysroot=%s' % sysroot] commands.RunBuildScript(self._build_root, cmd, chromite_cmd=True, enter_chroot=True, sudo=True, extra_env=self._portage_extra_env) # NOTE: Make sure that the overlay directory is owned root:root and has # 0o755 perms; apparently, these things are preserved through # tarring/untarring and might cause havoc if overlooked. os.chmod(overlay_dir, 0o755) cros_build_lib.SudoRunCommand(['chown', 'root:root', overlay_dir]) CreateTarball(overlay_dir, overlay_tarball_template % {'toolchains': toolchains_str}) generated.add(toolchains_str)
def testMountWriteUnmountRead(self): mount_call = self.PatchObject(osutils, 'MountDir') umount_call = self.PatchObject(osutils, 'UmountDir') for cleanup in (True, False): with osutils.MountOverlayContext(self.lowerdir, self.upperdir, self.mergeddir, cleanup=cleanup): mount_call.assert_any_call( 'overlay', self.mergeddir, fs_type='overlay', makedirs=False, mount_opts=('lowerdir=%s' % self.lowerdir, 'upperdir=%s' % self.upperdir, mock.ANY), quiet=mock.ANY) umount_call.assert_any_call(self.mergeddir, cleanup=cleanup)
def testNoValidWorkdirFallback(self): """Test that we fallback to overlayfs when no valid workdir is found..""" def _FailFileSystemCheck(_path1, _path2): return False check_filesystem = self.PatchObject(osutils, '_SameFileSystem') check_filesystem.side_effect = _FailFileSystemCheck mount_call = self.PatchObject(osutils, 'MountDir') umount_call = self.PatchObject(osutils, 'UmountDir') for cleanup in (True, False): with osutils.MountOverlayContext(self.lowerdir, self.upperdir, self.mergeddir, cleanup=cleanup): mount_call.assert_any_call( 'overlayfs', self.mergeddir, fs_type='overlayfs', makedirs=False, mount_opts=('lowerdir=%s' % self.lowerdir, 'upperdir=%s' % self.upperdir), quiet=mock.ANY) umount_call.assert_any_call(self.mergeddir, cleanup=cleanup)