示例#1
0
def _archive_copy(src_st, src_path, dest_path):
	"""
	Copy file from src_path to dest_path. Regular files and symlinks
	are supported. If an EnvironmentError occurs, then it is logged
	to stderr.

	@param src_st: source file lstat result
	@type src_st: posix.stat_result
	@param src_path: source file path
	@type src_path: str
	@param dest_path: destination file path
	@type dest_path: str
	"""
	# Remove destination file in order to ensure that the following
	# symlink or copy2 call won't fail (see bug #535850).
	try:
		os.unlink(dest_path)
	except OSError:
		pass
	try:
		if stat.S_ISLNK(src_st.st_mode):
			os.symlink(os.readlink(src_path), dest_path)
		else:
			shutil.copy2(src_path, dest_path)
	except EnvironmentError as e:
		portage.util.writemsg(
			_('dispatch-conf: Error copying %(src_path)s to '
			'%(dest_path)s: %(reason)s\n') % {
				"src_path": src_path,
				"dest_path": dest_path,
				"reason": e
			}, noiselevel=-1)
示例#2
0
def _prepare_fake_distdir(settings, alist):
	orig_distdir = settings["DISTDIR"]
	edpath = os.path.join(settings["PORTAGE_BUILDDIR"], "distdir")
	portage.util.ensure_dirs(edpath, gid=portage_gid, mode=0o755)

	# Remove any unexpected files or directories.
	for x in os.listdir(edpath):
		symlink_path = os.path.join(edpath, x)
		st = os.lstat(symlink_path)
		if x in alist and stat.S_ISLNK(st.st_mode):
			continue
		if stat.S_ISDIR(st.st_mode):
			shutil.rmtree(symlink_path)
		else:
			os.unlink(symlink_path)

	# Check for existing symlinks and recreate if necessary.
	for x in alist:
		symlink_path = os.path.join(edpath, x)
		target = os.path.join(orig_distdir, x)
		try:
			link_target = os.readlink(symlink_path)
		except OSError:
			os.symlink(target, symlink_path)
		else:
			if link_target != target:
				os.unlink(symlink_path)
				os.symlink(target, symlink_path)
示例#3
0
def _archive_copy(src_st, src_path, dest_path):
    """
    Copy file from src_path to dest_path. Regular files and symlinks
    are supported. If an EnvironmentError occurs, then it is logged
    to stderr.

    @param src_st: source file lstat result
    @type src_st: posix.stat_result
    @param src_path: source file path
    @type src_path: str
    @param dest_path: destination file path
    @type dest_path: str
    """
    # Remove destination file in order to ensure that the following
    # symlink or copy2 call won't fail (see bug #535850).
    try:
        os.unlink(dest_path)
    except OSError:
        pass
    try:
        if stat.S_ISLNK(src_st.st_mode):
            os.symlink(os.readlink(src_path), dest_path)
        else:
            shutil.copy2(src_path, dest_path)
    except EnvironmentError as e:
        portage.util.writemsg(
            _("dispatch-conf: Error copying %(src_path)s to "
              "%(dest_path)s: %(reason)s\n") % {
                  "src_path": src_path,
                  "dest_path": dest_path,
                  "reason": e
              },
            noiselevel=-1,
        )
示例#4
0
def _prepare_fake_filesdir(settings):
	real_filesdir = settings["O"]+"/files"
	symlink_path = settings["FILESDIR"]

	try:
		link_target = os.readlink(symlink_path)
	except OSError:
		os.symlink(real_filesdir, symlink_path)
	else:
		if link_target != real_filesdir:
			os.unlink(symlink_path)
			os.symlink(real_filesdir, symlink_path)
示例#5
0
 def modify_files(dir_path):
     for name in os.listdir(dir_path):
         path = os.path.join(dir_path, name)
         st = os.lstat(path)
         if stat.S_ISREG(st.st_mode):
             with io.open(path, mode='a',
                          encoding=_encodings["stdio"]) as f:
                 f.write("modified at %d\n" % time.time())
         elif stat.S_ISLNK(st.st_mode):
             old_dest = os.readlink(path)
             os.unlink(path)
             os.symlink(old_dest + " modified at %d" % time.time(),
                        path)
示例#6
0
		def modify_files(dir_path):
			for name in os.listdir(dir_path):
				path = os.path.join(dir_path, name)
				st = os.lstat(path)
				if stat.S_ISREG(st.st_mode):
					with io.open(path, mode='a',
						encoding=_encodings["stdio"]) as f:
						f.write("modified at %d\n" % time.time())
				elif stat.S_ISLNK(st.st_mode):
					old_dest = os.readlink(path)
					os.unlink(path)
					os.symlink(old_dest +
						" modified at %d" % time.time(), path)
示例#7
0
def diff_mixed(func, file1, file2):
    tempdir = None
    try:
        if os.path.islink(file1) and \
         not os.path.islink(file2) and \
         os.path.isfile(file1) and \
         os.path.isfile(file2):
            # If a regular file replaces a symlink to a regular
            # file, then show the diff between the regular files
            # (bug #330221).
            diff_files = (file2, file2)
        else:
            files = [file1, file2]
            diff_files = [file1, file2]
            for i in range(len(diff_files)):
                try:
                    st = os.lstat(diff_files[i])
                except OSError:
                    st = None
                if st is not None and stat.S_ISREG(st.st_mode):
                    continue

                if tempdir is None:
                    tempdir = tempfile.mkdtemp()
                diff_files[i] = os.path.join(tempdir, "%d" % i)
                if st is None:
                    content = "/dev/null\n"
                elif stat.S_ISLNK(st.st_mode):
                    link_dest = os.readlink(files[i])
                    content = "SYM: %s -> %s\n" % \
                     (file1, link_dest)
                elif stat.S_ISDIR(st.st_mode):
                    content = "DIR: %s\n" % (file1, )
                elif stat.S_ISFIFO(st.st_mode):
                    content = "FIF: %s\n" % (file1, )
                else:
                    content = "DEV: %s\n" % (file1, )
                with io.open(diff_files[i],
                             mode='w',
                             encoding=_encodings['stdio']) as f:
                    f.write(content)

        return func(diff_files[0], diff_files[1])

    finally:
        if tempdir is not None:
            shutil.rmtree(tempdir)
示例#8
0
def diff_mixed(func, file1, file2):
	tempdir = None
	try:
		if os.path.islink(file1) and \
			not os.path.islink(file2) and \
			os.path.isfile(file1) and \
			os.path.isfile(file2):
			# If a regular file replaces a symlink to a regular
			# file, then show the diff between the regular files
			# (bug #330221).
			diff_files = (file2, file2)
		else:
			files = [file1, file2]
			diff_files = [file1, file2]
			for i in range(len(diff_files)):
				try:
					st = os.lstat(diff_files[i])
				except OSError:
					st = None
				if st is not None and stat.S_ISREG(st.st_mode):
					continue

				if tempdir is None:
					tempdir = tempfile.mkdtemp()
				diff_files[i] = os.path.join(tempdir, "%d" % i)
				if st is None:
					content = "/dev/null\n"
				elif stat.S_ISLNK(st.st_mode):
					link_dest = os.readlink(files[i])
					content = "SYM: %s -> %s\n" % \
						(file1, link_dest)
				elif stat.S_ISDIR(st.st_mode):
					content = "DIR: %s\n" % (file1,)
				elif stat.S_ISFIFO(st.st_mode):
					content = "FIF: %s\n" % (file1,)
				else:
					content = "DEV: %s\n" % (file1,)
				with io.open(diff_files[i], mode='w',
					encoding=_encodings['stdio']) as f:
					f.write(content)

		return func(diff_files[0], diff_files[1])

	finally:
		if tempdir is not None:
			shutil.rmtree(tempdir)
示例#9
0
	def pruneNonExisting(self):
		""" Remove all records for objects that no longer exist on the filesystem. """

		os = _os_merge

		for cps in list(self._data):
			cpv, counter, _paths = self._data[cps]

			paths = []
			hardlinks = set()
			symlinks = {}
			for f in _paths:
				f_abs = os.path.join(self._root, f.lstrip(os.sep))
				try:
					lst = os.lstat(f_abs)
				except OSError:
					continue
				if stat.S_ISLNK(lst.st_mode):
					try:
						symlinks[f] = os.readlink(f_abs)
					except OSError:
						continue
				elif stat.S_ISREG(lst.st_mode):
					hardlinks.add(f)
					paths.append(f)

			# Only count symlinks as preserved if they still point to a hardink
			# in the same directory, in order to handle cases where a tool such
			# as eselect-opengl has updated the symlink to point to a hardlink
			# in a different directory (see bug #406837). The unused hardlink
			# is automatically found by _find_unused_preserved_libs, since the
			# soname symlink no longer points to it. After the hardlink is
			# removed by _remove_preserved_libs, it calls pruneNonExisting
			# which eliminates the irrelevant symlink from the registry here.
			for f, target in symlinks.items():
				if abssymlink(f, target=target) in hardlinks:
					paths.append(f)

			if len(paths) > 0:
				self._data[cps] = (cpv, counter, paths)
			else:
				del self._data[cps]
示例#10
0
    def pruneNonExisting(self):
        """Remove all records for objects that no longer exist on the filesystem."""

        os = _os_merge

        for cps in list(self._data):
            cpv, counter, _paths = self._data[cps]

            paths = []
            hardlinks = set()
            symlinks = {}
            for f in _paths:
                f_abs = os.path.join(self._root, f.lstrip(os.sep))
                try:
                    lst = os.lstat(f_abs)
                except OSError:
                    continue
                if stat.S_ISLNK(lst.st_mode):
                    try:
                        symlinks[f] = os.readlink(f_abs)
                    except OSError:
                        continue
                elif stat.S_ISREG(lst.st_mode):
                    hardlinks.add(f)
                    paths.append(f)

            # Only count symlinks as preserved if they still point to a hardink
            # in the same directory, in order to handle cases where a tool such
            # as eselect-opengl has updated the symlink to point to a hardlink
            # in a different directory (see bug #406837). The unused hardlink
            # is automatically found by _find_unused_preserved_libs, since the
            # soname symlink no longer points to it. After the hardlink is
            # removed by _remove_preserved_libs, it calls pruneNonExisting
            # which eliminates the irrelevant symlink from the registry here.
            for f, target in symlinks.items():
                if abssymlink(f, target=target) in hardlinks:
                    paths.append(f)

            if len(paths) > 0:
                self._data[cps] = (cpv, counter, paths)
            else:
                del self._data[cps]
示例#11
0
def _prepare_workdir(mysettings):
	workdir_mode = 0o700
	try:
		mode = mysettings["PORTAGE_WORKDIR_MODE"]
		if mode.isdigit():
			parsed_mode = int(mode, 8)
		elif mode == "":
			raise KeyError()
		else:
			raise ValueError()
		if parsed_mode & 0o7777 != parsed_mode:
			raise ValueError("Invalid file mode: %s" % mode)
		else:
			workdir_mode = parsed_mode
	except KeyError as e:
		writemsg(_("!!! PORTAGE_WORKDIR_MODE is unset, using %s.\n") % oct(workdir_mode))
	except ValueError as e:
		if len(str(e)) > 0:
			writemsg("%s\n" % e)
		writemsg(_("!!! Unable to parse PORTAGE_WORKDIR_MODE='%s', using %s.\n") % \
		(mysettings["PORTAGE_WORKDIR_MODE"], oct(workdir_mode)))
	mysettings["PORTAGE_WORKDIR_MODE"] = oct(workdir_mode).replace('o', '')
	try:
		apply_secpass_permissions(mysettings["WORKDIR"],
		uid=portage_uid, gid=portage_gid, mode=workdir_mode)
	except FileNotFound:
		pass # ebuild.sh will create it

	if mysettings.get("PORTAGE_LOGDIR", "") == "":
		while "PORTAGE_LOGDIR" in mysettings:
			del mysettings["PORTAGE_LOGDIR"]
	if "PORTAGE_LOGDIR" in mysettings:
		try:
			modified = ensure_dirs(mysettings["PORTAGE_LOGDIR"])
			if modified:
				# Only initialize group/mode if the directory doesn't
				# exist, so that we don't override permissions if they
				# were previously set by the administrator.
				# NOTE: These permissions should be compatible with our
				# default logrotate config as discussed in bug 374287.
				apply_secpass_permissions(mysettings["PORTAGE_LOGDIR"],
					uid=portage_uid, gid=portage_gid, mode=0o2770)
		except PortageException as e:
			writemsg("!!! %s\n" % str(e), noiselevel=-1)
			writemsg(_("!!! Permission issues with PORTAGE_LOGDIR='%s'\n") % \
				mysettings["PORTAGE_LOGDIR"], noiselevel=-1)
			writemsg(_("!!! Disabling logging.\n"), noiselevel=-1)
			while "PORTAGE_LOGDIR" in mysettings:
				del mysettings["PORTAGE_LOGDIR"]

	compress_log_ext = ''
	if 'compress-build-logs' in mysettings.features:
		compress_log_ext = '.gz'

	logdir_subdir_ok = False
	if "PORTAGE_LOGDIR" in mysettings and \
		os.access(mysettings["PORTAGE_LOGDIR"], os.W_OK):
		logdir = normalize_path(mysettings["PORTAGE_LOGDIR"])
		logid_path = os.path.join(mysettings["PORTAGE_BUILDDIR"], ".logid")
		if not os.path.exists(logid_path):
			open(_unicode_encode(logid_path), 'w').close()
		logid_time = _unicode_decode(time.strftime("%Y%m%d-%H%M%S",
			time.gmtime(os.stat(logid_path).st_mtime)),
			encoding=_encodings['content'], errors='replace')

		if "split-log" in mysettings.features:
			log_subdir = os.path.join(logdir, "build", mysettings["CATEGORY"])
			mysettings["PORTAGE_LOG_FILE"] = os.path.join(
				log_subdir, "%s:%s.log%s" %
				(mysettings["PF"], logid_time, compress_log_ext))
		else:
			log_subdir = logdir
			mysettings["PORTAGE_LOG_FILE"] = os.path.join(
				logdir, "%s:%s:%s.log%s" % \
				(mysettings["CATEGORY"], mysettings["PF"], logid_time,
				compress_log_ext))

		if log_subdir is logdir:
			logdir_subdir_ok = True
		else:
			try:
				_ensure_log_subdirs(logdir, log_subdir)
			except PortageException as e:
				writemsg("!!! %s\n" % (e,), noiselevel=-1)

			if os.access(log_subdir, os.W_OK):
				logdir_subdir_ok = True
			else:
				writemsg("!!! %s: %s\n" %
					(_("Permission Denied"), log_subdir), noiselevel=-1)

	tmpdir_log_path = os.path.join(
		mysettings["T"], "build.log%s" % compress_log_ext)
	if not logdir_subdir_ok:
		# NOTE: When sesandbox is enabled, the local SELinux security policies
		# may not allow output to be piped out of the sesandbox domain. The
		# current policy will allow it to work when a pty is available, but
		# not through a normal pipe. See bug #162404.
		mysettings["PORTAGE_LOG_FILE"] = tmpdir_log_path
	else:
		# Create a symlink from tmpdir_log_path to PORTAGE_LOG_FILE, as
		# requested in bug #412865.
		make_new_symlink = False
		try:
			target = os.readlink(tmpdir_log_path)
		except OSError:
			make_new_symlink = True
		else:
			if target != mysettings["PORTAGE_LOG_FILE"]:
				make_new_symlink = True
		if make_new_symlink:
			try:
				os.unlink(tmpdir_log_path)
			except OSError:
				pass
			os.symlink(mysettings["PORTAGE_LOG_FILE"], tmpdir_log_path)