Example #1
0
def detect_vcs_conflicts(options, vcs):
	"""Determine if the checkout has problems like cvs conflicts.
	
	If you want more vcs support here just keep adding if blocks...
	This could be better.
	
	TODO(antarus): Also this should probably not call sys.exit() as
	repoman is run on >1 packages and one failure should not cause
	subsequent packages to fail.
	
	Args:
		vcs - A string identifying the version control system in use
	Returns:
		None (calls sys.exit on fatal problems)
	"""
	retval = ("","")
	if vcs == 'cvs':
		logging.info("Performing a " + output.green("cvs -n up") + \
			" with a little magic grep to check for updates.")
		retval = subprocess_getstatusoutput("cvs -n up 2>/dev/null | " + \
			"egrep '^[^\?] .*' | " + \
			"egrep -v '^. .*/digest-[^/]+|^cvs server: .* -- ignored$'")
	if vcs == 'svn':
		logging.info("Performing a " + output.green("svn status -u") + \
			" with a little magic grep to check for updates.")
		retval = subprocess_getstatusoutput("svn status -u 2>&1 | " + \
			"egrep -v '^.  +.*/digest-[^/]+' | " + \
			"head -n-1")

	if vcs in ['cvs', 'svn']:
		mylines = retval[1].splitlines()
		myupdates = []
		for line in mylines:
			if not line:
				continue
			if line[0] not in " UPMARD": # unmodified(svn),Updates,Patches,Modified,Added,Removed/Replaced(svn),Deleted(svn)
				# Stray Manifest is fine, we will readd it anyway.
				if line[0] == '?' and line[1:].lstrip() == 'Manifest':
					continue
				logging.error(red("!!! Please fix the following issues reported " + \
					"from cvs: ")+green("(U,P,M,A,R,D are ok)"))
				logging.error(red("!!! Note: This is a pretend/no-modify pass..."))
				logging.error(retval[1])
				sys.exit(1)
			elif vcs == 'cvs' and line[0] in "UP":
				myupdates.append(line[2:])
			elif vcs == 'svn' and line[8] == '*':
				myupdates.append(line[9:].lstrip(" 1234567890"))

		if myupdates:
			logging.info(green("Fetching trivial updates..."))
			if options.pretend:
				logging.info("(" + vcs + " update " + " ".join(myupdates) + ")")
				retval = os.EX_OK
			else:
				retval = os.system(vcs + " update " + " ".join(myupdates))
			if retval != os.EX_OK:
				logging.fatal("!!! " + vcs + " exited with an error. Terminating.")
				sys.exit(retval)
Example #2
0
    def testBashSyntax(self):
        for parent, dirs, files in os.walk(PORTAGE_BIN_PATH):
            parent = _unicode_decode(parent,
                                     encoding=_encodings['fs'],
                                     errors='strict')
            for x in files:
                x = _unicode_decode(x,
                                    encoding=_encodings['fs'],
                                    errors='strict')
                ext = x.split('.')[-1]
                if ext in ('.py', '.pyc', '.pyo'):
                    continue
                x = os.path.join(parent, x)
                st = os.lstat(x)
                if not stat.S_ISREG(st.st_mode):
                    continue

                # Check for bash shebang
                f = open(
                    _unicode_encode(x,
                                    encoding=_encodings['fs'],
                                    errors='strict'), 'rb')
                line = _unicode_decode(f.readline(),
                                       encoding=_encodings['content'],
                                       errors='replace')
                f.close()
                if line[:2] == '#!' and \
                 'bash' in line:
                    cmd = "%s -n %s" % (_shell_quote(BASH_BINARY),
                                        _shell_quote(x))
                    status, output = subprocess_getstatusoutput(cmd)
                    self.assertEqual(os.WIFEXITED(status) and \
                     os.WEXITSTATUS(status) == os.EX_OK, True, msg=output)
Example #3
0
def get_term_size():
	"""
	Get the number of lines and columns of the tty that is connected to
	stdout.  Returns a tuple of (lines, columns) or (-1, -1) if an error
	occurs. The curses module is used if available, otherwise the output of
	`stty size` is parsed.
	"""
	if not sys.stdout.isatty():
		return -1, -1
	try:
		import curses
		try:
			curses.setupterm()
			return curses.tigetnum('lines'), curses.tigetnum('cols')
		except curses.error:
			pass
	except ImportError:
		pass
	st, out = portage.subprocess_getstatusoutput('stty size')
	if st == os.EX_OK:
		out = out.split()
		if len(out) == 2:
			try:
				return int(out[0]), int(out[1])
			except ValueError:
				pass
	return -1, -1
	def testBashSyntax(self):
		for parent, dirs, files in os.walk(PORTAGE_BIN_PATH):
			parent = _unicode_decode(parent,
				encoding=_encodings['fs'], errors='strict')
			for x in files:
				x = _unicode_decode(x,
					encoding=_encodings['fs'], errors='strict')
				ext = x.split('.')[-1]
				if ext in ('.py', '.pyc', '.pyo'):
					continue
				x = os.path.join(parent, x)
				st = os.lstat(x)
				if not stat.S_ISREG(st.st_mode):
					continue

				# Check for bash shebang
				f = open(_unicode_encode(x,
					encoding=_encodings['fs'], errors='strict'), 'rb')
				line = _unicode_decode(f.readline(),
					encoding=_encodings['content'], errors='replace')
				f.close()
				if line[:2] == '#!' and \
					'bash' in line:
					cmd = "%s -n %s" % (_shell_quote(BASH_BINARY), _shell_quote(x))
					status, output = subprocess_getstatusoutput(cmd)
					self.assertEqual(os.WIFEXITED(status) and \
						os.WEXITSTATUS(status) == os.EX_OK, True, msg=output)
Example #5
0
def get_term_size():
	"""
	Get the number of lines and columns of the tty that is connected to
	stdout.  Returns a tuple of (lines, columns) or (0, 0) if an error
	occurs. The curses module is used if available, otherwise the output of
	`stty size` is parsed. The lines and columns values are guaranteed to be
	greater than or equal to zero, since a negative COLUMNS variable is
	known to prevent some commands from working (see bug #394091).
	"""
	if not sys.stdout.isatty():
		return (0, 0)
	try:
		import curses
		try:
			curses.setupterm()
			return curses.tigetnum('lines'), curses.tigetnum('cols')
		except curses.error:
			pass
	except ImportError:
		pass
	st, out = portage.subprocess_getstatusoutput('stty size')
	if st == os.EX_OK:
		out = out.split()
		if len(out) == 2:
			try:
				val = (int(out[0]), int(out[1]))
			except ValueError:
				pass
			else:
				if val[0] >= 0 and val[1] >= 0:
					return val
	return (0, 0)
Example #6
0
def get_term_size():
    """
	Get the number of lines and columns of the tty that is connected to
	stdout.  Returns a tuple of (lines, columns) or (0, 0) if an error
	occurs. The curses module is used if available, otherwise the output of
	`stty size` is parsed. The lines and columns values are guaranteed to be
	greater than or equal to zero, since a negative COLUMNS variable is
	known to prevent some commands from working (see bug #394091).
	"""
    if not sys.stdout.isatty():
        return (0, 0)
    try:
        import curses
        try:
            curses.setupterm()
            return curses.tigetnum('lines'), curses.tigetnum('cols')
        except curses.error:
            pass
    except ImportError:
        pass
    st, out = portage.subprocess_getstatusoutput('stty size')
    if st == os.EX_OK:
        out = out.split()
        if len(out) == 2:
            try:
                val = (int(out[0]), int(out[1]))
            except ValueError:
                pass
            else:
                if val[0] >= 0 and val[1] >= 0:
                    return val
    return (0, 0)
def find_updated_config_files(target_root, config_protect):
	"""
	Return a tuple of configuration files that needs to be updated.
	The tuple contains lists organized like this:
	[ protected_dir, file_list ]
	If the protected config isn't a protected_dir but a procted_file, list is:
	[ protected_file, None ]
	If no configuration files needs to be updated, None is returned
	"""

	os = _os_merge

	if config_protect:
		# directories with some protect files in them
		for x in config_protect:
			files = []

			x = os.path.join(target_root, x.lstrip(os.path.sep))
			if not os.access(x, os.W_OK):
				continue
			try:
				mymode = os.lstat(x).st_mode
			except OSError:
				continue

			if stat.S_ISLNK(mymode):
				# We want to treat it like a directory if it
				# is a symlink to an existing directory.
				try:
					real_mode = os.stat(x).st_mode
					if stat.S_ISDIR(real_mode):
						mymode = real_mode
				except OSError:
					pass

			if stat.S_ISDIR(mymode):
				mycommand = \
					"find '%s' -name '.*' -type d -prune -o -name '._cfg????_*'" % x
			else:
				mycommand = "find '%s' -maxdepth 1 -name '._cfg????_%s'" % \
						os.path.split(x.rstrip(os.path.sep))
			mycommand += " ! -name '.*~' ! -iname '.*.bak' -print0"
			a = subprocess_getstatusoutput(mycommand)

			if a[0] == 0:
				files = a[1].split('\0')
				# split always produces an empty string as the last element
				if files and not files[-1]:
					del files[-1]
				if files:
					if stat.S_ISDIR(mymode):
						yield (x, files)
					else:
						yield (x, None)
Example #8
0
def find_updated_config_files(target_root, config_protect):
	"""
	Return a tuple of configuration files that needs to be updated.
	The tuple contains lists organized like this:
	[ protected_dir, file_list ]
	If the protected config isn't a protected_dir but a procted_file, list is:
	[ protected_file, None ]
	If no configuration files needs to be updated, None is returned
	"""

	os = _os_merge

	if config_protect:
		# directories with some protect files in them
		for x in config_protect:
			files = []

			x = os.path.join(target_root, x.lstrip(os.path.sep))
			if not os.access(x, os.W_OK):
				continue
			try:
				mymode = os.lstat(x).st_mode
			except OSError:
				continue

			if stat.S_ISLNK(mymode):
				# We want to treat it like a directory if it
				# is a symlink to an existing directory.
				try:
					real_mode = os.stat(x).st_mode
					if stat.S_ISDIR(real_mode):
						mymode = real_mode
				except OSError:
					pass

			if stat.S_ISDIR(mymode):
				mycommand = \
					"find '%s' -name '.*' -type d -prune -o -name '._cfg????_*'" % x
			else:
				mycommand = "find '%s' -maxdepth 1 -name '._cfg????_%s'" % \
						os.path.split(x.rstrip(os.path.sep))
			mycommand += " ! -name '.*~' ! -iname '.*.bak' -print0"
			a = subprocess_getstatusoutput(mycommand)

			if a[0] == 0:
				files = a[1].split('\0')
				# split always produces an empty string as the last element
				if files and not files[-1]:
					del files[-1]
				if files:
					if stat.S_ISDIR(mymode):
						yield (x, files)
					else:
						yield (x, None)
Example #9
0
def diffstatusoutput_len(cmd):
    """
    Execute the string cmd in a shell with getstatusoutput() and return a
    2-tuple (status, output_length). If getstatusoutput() raises
    UnicodeDecodeError (known to happen with python3.1), return a
    2-tuple (1, 1). This provides a simple way to check for non-zero
    output length of diff commands, while providing simple handling of
    UnicodeDecodeError when necessary.
    """
    try:
        status, output = portage.subprocess_getstatusoutput(cmd)
        return (status, len(output))
    except UnicodeDecodeError:
        return (1, 1)
Example #10
0
			def _get_target(self):
				global userpriv_groups
				if userpriv_groups is not self:
					return userpriv_groups
				userpriv_groups = _userpriv_groups
				# Get a list of group IDs for the portage user. Do not use
				# grp.getgrall() since it is known to trigger spurious
				# SIGPIPE problems with nss_ldap.
				mystatus, myoutput = \
					portage.subprocess_getstatusoutput("id -G %s" % _portage_uname)
				if mystatus == os.EX_OK:
					for x in myoutput.split():
						try:
							userpriv_groups.append(int(x))
						except ValueError:
							pass
					userpriv_groups[:] = sorted(set(userpriv_groups))
				return userpriv_groups
Example #11
0
 def _get_target(self):
     global userpriv_groups
     if userpriv_groups is not self:
         return userpriv_groups
     userpriv_groups = _userpriv_groups
     # Get a list of group IDs for the portage user. Do not use
     # grp.getgrall() since it is known to trigger spurious
     # SIGPIPE problems with nss_ldap.
     mystatus, myoutput = \
      portage.subprocess_getstatusoutput("id -G %s" % _portage_uname)
     if mystatus == os.EX_OK:
         for x in myoutput.split():
             try:
                 userpriv_groups.append(int(x))
             except ValueError:
                 pass
         userpriv_groups[:] = sorted(set(userpriv_groups))
     return userpriv_groups
Example #12
0
def detect_vcs_conflicts(options, vcs):
    """Determine if the checkout has problems like cvs conflicts.
	
	If you want more vcs support here just keep adding if blocks...
	This could be better.
	
	TODO(antarus): Also this should probably not call sys.exit() as
	repoman is run on >1 packages and one failure should not cause
	subsequent packages to fail.
	
	Args:
		vcs - A string identifying the version control system in use
	Returns:
		None (calls sys.exit on fatal problems)
	"""
    retval = ("", "")
    if vcs == 'cvs':
        logging.info("Performing a " + output.green("cvs -n up") + \
         " with a little magic grep to check for updates.")
        retval = subprocess_getstatusoutput("cvs -n up 2>/dev/null | " + \
         "egrep '^[^\?] .*' | " + \
         "egrep -v '^. .*/digest-[^/]+|^cvs server: .* -- ignored$'")
    if vcs == 'svn':
        logging.info("Performing a " + output.green("svn status -u") + \
         " with a little magic grep to check for updates.")
        retval = subprocess_getstatusoutput("svn status -u 2>&1 | " + \
         "egrep -v '^.  +.*/digest-[^/]+' | " + \
         "head -n-1")

    if vcs in ['cvs', 'svn']:
        mylines = retval[1].splitlines()
        myupdates = []
        for line in mylines:
            if not line:
                continue
            if line[0] not in " UPMARD":  # unmodified(svn),Updates,Patches,Modified,Added,Removed/Replaced(svn),Deleted(svn)
                # Stray Manifest is fine, we will readd it anyway.
                if line[0] == '?' and line[1:].lstrip() == 'Manifest':
                    continue
                logging.error(red("!!! Please fix the following issues reported " + \
                 "from cvs: ")+green("(U,P,M,A,R,D are ok)"))
                logging.error(
                    red("!!! Note: This is a pretend/no-modify pass..."))
                logging.error(retval[1])
                sys.exit(1)
            elif vcs == 'cvs' and line[0] in "UP":
                myupdates.append(line[2:])
            elif vcs == 'svn' and line[8] == '*':
                myupdates.append(line[9:].lstrip(" 1234567890"))

        if myupdates:
            logging.info(green("Fetching trivial updates..."))
            if options.pretend:
                logging.info("(" + vcs + " update " + " ".join(myupdates) +
                             ")")
                retval = os.EX_OK
            else:
                retval = os.system(vcs + " update " + " ".join(myupdates))
            if retval != os.EX_OK:
                logging.fatal("!!! " + vcs +
                              " exited with an error. Terminating.")
                sys.exit(retval)
Example #13
0
def _get_global(k):
	if k in _initialized_globals:
		return globals()[k]

	if k in ('portage_gid', 'portage_uid', 'secpass'):
		global portage_gid, portage_uid, secpass
		secpass = 0
		if uid == 0:
			secpass = 2
		elif portage.const.EPREFIX:
			secpass = 2
		#Discover the uid and gid of the portage user/group
		try:
			portage_uid = pwd.getpwnam(_get_global('_portage_username')).pw_uid
			_portage_grpname = _get_global('_portage_grpname')
			if platform.python_implementation() == 'PyPy':
				# Somehow this prevents "TypeError: expected string" errors
				# from grp.getgrnam() with PyPy 1.7
				_portage_grpname = str(_portage_grpname)
			portage_gid = grp.getgrnam(_portage_grpname).gr_gid
			if secpass < 1 and portage_gid in os.getgroups():
				secpass = 1
		except KeyError:
			portage_uid = 0
			portage_gid = 0
			writemsg(colorize("BAD",
				_("portage: 'portage' user or group missing.")) + "\n", noiselevel=-1)
			writemsg(_(
				"         For the defaults, line 1 goes into passwd, "
				"and 2 into group.\n"), noiselevel=-1)
			writemsg(colorize("GOOD",
				"         portage:x:250:250:portage:/var/tmp/portage:/bin/false") \
				+ "\n", noiselevel=-1)
			writemsg(colorize("GOOD", "         portage::250:portage") + "\n",
				noiselevel=-1)
			portage_group_warning()

		_initialized_globals.add('portage_gid')
		_initialized_globals.add('portage_uid')
		_initialized_globals.add('secpass')

		if k == 'portage_gid':
			return portage_gid
		elif k == 'portage_uid':
			return portage_uid
		elif k == 'secpass':
			return secpass
		else:
			raise AssertionError('unknown name: %s' % k)

	elif k == 'userpriv_groups':
		v = [portage_gid]
		if secpass >= 2:
			# Get a list of group IDs for the portage user. Do not use
			# grp.getgrall() since it is known to trigger spurious
			# SIGPIPE problems with nss_ldap.
			mystatus, myoutput = \
				portage.subprocess_getstatusoutput("id -G %s" % _portage_username)
			if mystatus == os.EX_OK:
				for x in myoutput.split():
					try:
						v.append(int(x))
					except ValueError:
						pass
				v = sorted(set(v))

	# Avoid instantiating portage.settings when the desired
	# variable is set in os.environ.
	elif k in ('_portage_grpname', '_portage_username'):
		v = None
		if k == '_portage_grpname':
			env_key = 'PORTAGE_GRPNAME'
		else:
			env_key = 'PORTAGE_USERNAME'

		if env_key in os.environ:
			v = os.environ[env_key]
		elif hasattr(portage, 'settings'):
			v = portage.settings.get(env_key)
		elif portage.const.EPREFIX:
			# For prefix environments, default to the UID and GID of
			# the top-level EROOT directory. The config class has
			# equivalent code, but we also need to do it here if
			# _disable_legacy_globals() has been called.
			eroot = os.path.join(os.environ.get('ROOT', os.sep),
				portage.const.EPREFIX.lstrip(os.sep))
			try:
				eroot_st = os.stat(eroot)
			except OSError:
				pass
			else:
				if k == '_portage_grpname':
					try:
						grp_struct = grp.getgrgid(eroot_st.st_gid)
					except KeyError:
						pass
					else:
						v = grp_struct.gr_name
				else:
					try:
						pwd_struct = pwd.getpwuid(eroot_st.st_uid)
					except KeyError:
						pass
					else:
						v = pwd_struct.pw_name

		if v is None:
			v = 'portage'
	else:
		raise AssertionError('unknown name: %s' % k)

	globals()[k] = v
	_initialized_globals.add(k)
	return v
Example #14
0
    pass


# There is only one implementation for size
def getsize(filename):
    size = os.stat(filename).st_size
    return (size, size)


hashfunc_map["size"] = getsize

# end actual hash functions

prelink_capable = False
if os.path.exists(PRELINK_BINARY):
    results = portage.subprocess_getstatusoutput(
        "%s --version > /dev/null 2>&1" % (PRELINK_BINARY, ))
    if (results[0] >> 8) == 0:
        prelink_capable = 1
    del results


def is_prelinkable_elf(filename):
    f = _open_file(filename)
    try:
        magic = f.read(17)
    finally:
        f.close()
    return (len(magic) == 17 and magic.startswith(b'\x7fELF')
            and magic[16] in (b'\x02', b'\x03'))  # 2=ET_EXEC, 3=ET_DYN

Example #15
0
def _get_global(k):
    if k in _initialized_globals:
        return globals()[k]

    if k in ('portage_gid', 'portage_uid', 'secpass'):
        global portage_gid, portage_uid, secpass
        secpass = 0
        if uid == 0:
            secpass = 2
        elif portage.const.EPREFIX:
            secpass = 2
        #Discover the uid and gid of the portage user/group
        try:
            portage_uid = pwd.getpwnam(_get_global('_portage_username')).pw_uid
            _portage_grpname = _get_global('_portage_grpname')
            if platform.python_implementation() == 'PyPy':
                # Somehow this prevents "TypeError: expected string" errors
                # from grp.getgrnam() with PyPy 1.7
                _portage_grpname = str(_portage_grpname)
            portage_gid = grp.getgrnam(_portage_grpname).gr_gid
            if secpass < 1 and portage_gid in os.getgroups():
                secpass = 1
        except KeyError:
            portage_uid = 0
            portage_gid = 0
            writemsg(colorize(
                "BAD", _("portage: 'portage' user or group missing.")) + "\n",
                     noiselevel=-1)
            writemsg(_("         For the defaults, line 1 goes into passwd, "
                       "and 2 into group.\n"),
                     noiselevel=-1)
            writemsg(colorize("GOOD",
             "         portage:x:250:250:portage:/var/tmp/portage:/bin/false") \
             + "\n", noiselevel=-1)
            writemsg(colorize("GOOD", "         portage::250:portage") + "\n",
                     noiselevel=-1)
            portage_group_warning()

        _initialized_globals.add('portage_gid')
        _initialized_globals.add('portage_uid')
        _initialized_globals.add('secpass')

        if k == 'portage_gid':
            return portage_gid
        elif k == 'portage_uid':
            return portage_uid
        elif k == 'secpass':
            return secpass
        else:
            raise AssertionError('unknown name: %s' % k)

    elif k == 'userpriv_groups':
        v = [portage_gid]
        if secpass >= 2:
            # Get a list of group IDs for the portage user. Do not use
            # grp.getgrall() since it is known to trigger spurious
            # SIGPIPE problems with nss_ldap.
            mystatus, myoutput = \
             portage.subprocess_getstatusoutput("id -G %s" % _portage_username)
            if mystatus == os.EX_OK:
                for x in myoutput.split():
                    try:
                        v.append(int(x))
                    except ValueError:
                        pass
                v = sorted(set(v))

    # Avoid instantiating portage.settings when the desired
    # variable is set in os.environ.
    elif k in ('_portage_grpname', '_portage_username'):
        v = None
        if k == '_portage_grpname':
            env_key = 'PORTAGE_GRPNAME'
        else:
            env_key = 'PORTAGE_USERNAME'

        if env_key in os.environ:
            v = os.environ[env_key]
        elif hasattr(portage, 'settings'):
            v = portage.settings.get(env_key)
        elif portage.const.EPREFIX:
            # For prefix environments, default to the UID and GID of
            # the top-level EROOT directory. The config class has
            # equivalent code, but we also need to do it here if
            # _disable_legacy_globals() has been called.
            eroot = os.path.join(os.environ.get('ROOT', os.sep),
                                 portage.const.EPREFIX.lstrip(os.sep))
            try:
                eroot_st = os.stat(eroot)
            except OSError:
                pass
            else:
                if k == '_portage_grpname':
                    try:
                        grp_struct = grp.getgrgid(eroot_st.st_gid)
                    except KeyError:
                        pass
                    else:
                        v = grp_struct.gr_name
                else:
                    try:
                        pwd_struct = pwd.getpwuid(eroot_st.st_uid)
                    except KeyError:
                        pass
                    else:
                        v = pwd_struct.pw_name

        if v is None:
            v = 'portage'
    else:
        raise AssertionError('unknown name: %s' % k)

    globals()[k] = v
    _initialized_globals.add(k)
    return v
Example #16
0
	hashorigin_map["MD5"] = "python-fchksum"

except ImportError:
	pass

# There is only one implementation for size
def getsize(filename):
	size = os.stat(filename).st_size
	return (size, size)
hashfunc_map["size"] = getsize

# end actual hash functions

prelink_capable = False
if os.path.exists(PRELINK_BINARY):
	results = portage.subprocess_getstatusoutput(
		"%s --version > /dev/null 2>&1" % (PRELINK_BINARY,))
	if (results[0] >> 8) == 0:
		prelink_capable=1
	del results

def is_prelinkable_elf(filename):
	f = _open_file(filename)
	try:
		magic = f.read(17)
	finally:
		f.close()
	return (len(magic) == 17 and magic.startswith(b'\x7fELF') and
		magic[16] in (b'\x02', b'\x03')) # 2=ET_EXEC, 3=ET_DYN

def perform_md5(x, calc_prelink=0):
	return perform_checksum(x, "MD5", calc_prelink)[0]