[gentoo-commits] proj/portage:master commit in: lib/portage/, bin/, /

2022-09-09 Thread Michał Górny
commit: 020feffb39cd6c4c68a4a81be6ccd2426b062e8d
Author: Sheng Yu  protonmail  com>
AuthorDate: Fri Aug 19 20:40:59 2022 +
Commit: Michał Górny  gentoo  org>
CommitDate: Fri Sep  9 10:15:58 2022 +
URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=020feffb

Add gpkg-sign tool to sign exist GPKG files.

Signed-off-by: Sheng Yu  protonmail.com>
Signed-off-by: Michał Górny  gentoo.org>

 bin/gpkg-sign   | 68 +
 lib/portage/gpkg.py | 73 +
 setup.py|  1 +
 3 files changed, 142 insertions(+)

diff --git a/bin/gpkg-sign b/bin/gpkg-sign
new file mode 100755
index 0..57fc6ce98
--- /dev/null
+++ b/bin/gpkg-sign
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+import argparse
+import sys
+
+import portage
+import portage.exception
+
+portage._internal_caller = True
+from portage import gpkg
+
+
+def main(
+gpkg_file, keep_current_signature=False, allow_unsigned=False, 
skip_signed=False
+):
+eout = portage.output.EOutput()
+try:
+package = gpkg.gpkg(settings=portage.settings, gpkg_file=gpkg_file)
+if allow_unsigned:
+package.request_signature = False
+package._verify_binpkg()
+if skip_signed and package.signature_exist:
+eout.einfo(f"{gpkg_file} already signed, skipping.")
+return
+package.update_signature(keep_current_signature=keep_current_signature)
+eout.einfo(f"{gpkg_file} signed.")
+except portage.exception.FileNotFound:
+eout.eerror(f"File not found: {gpkg_file}")
+exit(1)
+except portage.exception.InvalidBinaryPackageFormat:
+eout.eerror(f"Invalid binary package format: {gpkg_file}")
+exit(1)
+except portage.exception.SignatureException:
+eout.eerror(f"Signature exception: {gpkg_file}")
+exit(1)
+
+
+if __name__ == "__main__":
+usage = "gpkg-sign [options] "
+parser = argparse.ArgumentParser(usage=usage)
+parser.add_argument(
+"--keep-current-signature",
+action="store_true",
+help="Keep existing signature when updating signature (default: 
false)",
+)
+parser.add_argument(
+"--allow-unsigned",
+action="store_true",
+help="Allow signing from unsigned packages when 
binpkg-request-signature is enabled (default: false)",
+)
+parser.add_argument(
+"--skip-signed",
+action="store_true",
+help="Skip signing if a package is already signed (default: false)",
+)
+options, args = parser.parse_known_args(sys.argv[1:])
+
+if not args:
+parser.error("no GPKG oackage file specified")
+
+main(
+args[0],
+keep_current_signature=options.keep_current_signature,
+allow_unsigned=options.allow_unsigned,
+skip_signed=options.skip_signed,
+)

diff --git a/lib/portage/gpkg.py b/lib/portage/gpkg.py
index 303773616..644ff412b 100644
--- a/lib/portage/gpkg.py
+++ b/lib/portage/gpkg.py
@@ -781,6 +781,7 @@ class gpkg:
 self.base_name = base_name
 self.checksums = []
 self.manifest_old = []
+signature_exist = None
 
 # Compression is the compression algorithm, if set to None will
 # not use compression.
@@ -1118,6 +1119,77 @@ class gpkg:
 
 shutil.move(tmp_gpkg_file_name, self.gpkg_file)
 
+def update_signature(self, keep_current_signature=False):
+"""
+Add / update signature in the gpkg file.
+if keep_current_signature is True, keep the current signature, 
otherwise, re-signing it.
+"""
+self.create_signature = True
+self._verify_binpkg()
+self.checksums = []
+
+with open(self.gpkg_file, "rb") as container:
+container_tar_format = self._get_tar_format(container)
+if container_tar_format is None:
+raise InvalidBinaryPackageFormat("Cannot identify tar format")
+
+# container
+tmp_gpkg_file_name = f"{self.gpkg_file}.{os.getpid()}"
+with tarfile.TarFile(
+name=tmp_gpkg_file_name, mode="w", format=container_tar_format
+) as container:
+# gpkg version
+gpkg_version_file = tarfile.TarInfo(self.gpkg_version)
+gpkg_version_file.mtime = datetime.utcnow().timestamp()
+container.addfile(gpkg_version_file)
+
+# reuse other stuffs
+with tarfile.open(self.gpkg_file, "r") as container_old:
+manifest_old = self.manifest_old.copy()
+file_list_old = [f[1] for f in manifest_old]
+
+for m in manifest_old:
+file_name_old = m[1]
+if os.path.basename(file_name_old).endswith(".sig"):
+continue
+  

[gentoo-commits] proj/portage:master commit in: lib/portage/, bin/install-qa-check.d/, bin/

2021-10-04 Thread Michał Górny
commit: 204537a426c8738528063c3c5226642de3b7d097
Author: Michał Górny  gentoo  org>
AuthorDate: Tue Sep 28 12:39:22 2021 +
Commit: Michał Górny  gentoo  org>
CommitDate: Mon Oct  4 07:27:46 2021 +
URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=204537a4

Prefix color vars with "PORTAGE_COLOR_"

Rename color variables used by einfo etc. to use "PORTAGE_COLOR_"
prefix.  Currently these variables are prone to being accidentally
ovewritten e.g. if an ebuild uses GOOD or BAD variables for some
purpose.  Using PORTAGE prefix should keep us safe.

As an extra benefit, this makes it trivial to grep for all uses of color
variables.

Signed-off-by: Michał Górny  gentoo.org>

 bin/install-qa-check.d/10ignored-flags |  4 ++--
 bin/isolated-functions.sh  | 42 +-
 bin/save-ebuild-env.sh | 16 +++--
 lib/portage/output.py  |  4 ++--
 4 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/bin/install-qa-check.d/10ignored-flags 
b/bin/install-qa-check.d/10ignored-flags
index 89706cd4c..7cd073578 100644
--- a/bin/install-qa-check.d/10ignored-flags
+++ b/bin/install-qa-check.d/10ignored-flags
@@ -52,7 +52,7 @@ ignored_flag_check() {
f=$(<"${T}"/scanelf-ignored-CFLAGS.log)
if [[ -n ${f} ]] ; then
__vecho -ne '\n'
-   eqawarn "${BAD}QA Notice: Files built without 
respecting CFLAGS have been detected${NORMAL}"
+   eqawarn "${PORTAGE_COLOR_BAD}QA Notice: Files 
built without respecting CFLAGS have been detected${PORTAGE_COLOR_NORMAL}"
eqawarn " Please include the following list of 
files in your report:"
eqawarn "${f}"
__vecho -ne '\n'
@@ -82,7 +82,7 @@ ignored_flag_check() {
f=$(<"${T}"/scanelf-ignored-LDFLAGS.log)
if [[ -n ${f} ]] ; then
__vecho -ne '\n'
-   eqawarn "${BAD}QA Notice: Files built without 
respecting LDFLAGS have been detected${NORMAL}"
+   eqawarn "${PORTAGE_COLOR_BAD}QA Notice: Files 
built without respecting LDFLAGS have been detected${PORTAGE_COLOR_NORMAL}"
eqawarn " Please include the following list of 
files in your report:"
eqawarn "${f}"
__vecho -ne '\n'

diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
index 5630dcf4c..3e79ea6e3 100644
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@ -255,7 +255,7 @@ __elog_base() {
shift
;;
*)
-   __vecho -e " ${BAD}*${NORMAL} Invalid use of internal 
function __elog_base(), next message will not be logged"
+   __vecho -e " 
${PORTAGE_COLOR_BAD}*${PORTAGE_COLOR_NORMAL} Invalid use of internal function 
__elog_base(), next message will not be logged"
return 1
;;
esac
@@ -270,7 +270,7 @@ eqawarn() {
__elog_base QA "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " $WARN*$NORMAL $REPLY" >&2
+   echo " ${PORTAGE_COLOR_WARN}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
done
LAST_E_CMD="eqawarn"
return 0
@@ -280,7 +280,7 @@ elog() {
__elog_base LOG "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " $GOOD*$NORMAL $REPLY" >&2
+   echo " ${PORTAGE_COLOR_GOOD}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
done
LAST_E_CMD="elog"
return 0
@@ -290,7 +290,7 @@ einfo() {
__elog_base INFO "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " $GOOD*$NORMAL $REPLY" >&2
+   echo " ${PORTAGE_COLOR_GOOD}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
done
LAST_E_CMD="einfo"
return 0
@@ -299,7 +299,7 @@ einfo() {
 einfon() {
__elog_base INFO "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
-   echo -ne " ${GOOD}*${NORMAL} $*" >&2
+   echo -ne " ${PORTAGE_COLOR_GOOD}*${PORTAGE_COLOR_NORMAL} $*" >&2
LAST_E_CMD="einfon"
return 0
 }
@@ -308,7 +308,7 @@ ewarn() {
__elog_base WARN "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " $WARN*$NORMAL $RC_INDENTATION$REPLY" >&2
+   echo " ${PORTAGE_COLOR_WARN}*${PORTAGE_COLOR_NORMAL} 

[gentoo-commits] proj/portage:master commit in: lib/portage/, bin/, lib/portage/elog/

2021-10-04 Thread Michał Górny
commit: 3ab738a7a5a81ee3d5b973e93a4d93f6e497a321
Author: Michał Górny  gentoo  org>
AuthorDate: Tue Sep 28 12:50:52 2021 +
Commit: Michał Górny  gentoo  org>
CommitDate: Mon Oct  4 07:27:46 2021 +
URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=3ab738a7

Use distinct colors for output msg types

Introduce distinct colors per output function.  For elog and eerror
the colors remain the same but the names change.  For einfo and eqawarn,
use darker colors to distinguish them.

Signed-off-by: Michał Górny  gentoo.org>

 bin/isolated-functions.sh| 30 +-
 bin/save-ebuild-env.sh   |  6 +++--
 lib/portage/elog/messages.py | 10 
 lib/portage/elog/mod_echo.py |  4 +--
 lib/portage/output.py| 59 ++--
 5 files changed, 81 insertions(+), 28 deletions(-)

diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
index 3e79ea6e3..df806d403 100644
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@ -270,7 +270,7 @@ eqawarn() {
__elog_base QA "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " ${PORTAGE_COLOR_WARN}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
+   echo " ${PORTAGE_COLOR_QAWARN}*${PORTAGE_COLOR_NORMAL} 
${REPLY}" >&2
done
LAST_E_CMD="eqawarn"
return 0
@@ -280,7 +280,7 @@ elog() {
__elog_base LOG "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " ${PORTAGE_COLOR_GOOD}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
+   echo " ${PORTAGE_COLOR_LOG}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
done
LAST_E_CMD="elog"
return 0
@@ -290,7 +290,7 @@ einfo() {
__elog_base INFO "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " ${PORTAGE_COLOR_GOOD}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
+   echo " ${PORTAGE_COLOR_INFO}*${PORTAGE_COLOR_NORMAL} ${REPLY}" 
>&2
done
LAST_E_CMD="einfo"
return 0
@@ -299,7 +299,7 @@ einfo() {
 einfon() {
__elog_base INFO "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
-   echo -ne " ${PORTAGE_COLOR_GOOD}*${PORTAGE_COLOR_NORMAL} $*" >&2
+   echo -ne " ${PORTAGE_COLOR_INFO}*${PORTAGE_COLOR_NORMAL} $*" >&2
LAST_E_CMD="einfon"
return 0
 }
@@ -318,7 +318,7 @@ eerror() {
__elog_base ERROR "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo >&2
echo -e "$@" | while read -r ; do
-   echo " ${PORTAGE_COLOR_BAD}*${PORTAGE_COLOR_NORMAL} 
${RC_INDENTATION}${REPLY}" >&2
+   echo " ${PORTAGE_COLOR_ERR}*${PORTAGE_COLOR_NORMAL} 
${RC_INDENTATION}${REPLY}" >&2
done
LAST_E_CMD="eerror"
return 0
@@ -378,12 +378,16 @@ __unset_colors() {
COLS=80
ENDCOL=
 
-   PORTAGE_COLOR_GOOD=
-   PORTAGE_COLOR_WARN=
PORTAGE_COLOR_BAD=
+   PORTAGE_COLOR_BRACKET=
+   PORTAGE_COLOR_ERR=
+   PORTAGE_COLOR_GOOD=
PORTAGE_COLOR_HILITE=
+   PORTAGE_COLOR_INFO=
+   PORTAGE_COLOR_LOG=
PORTAGE_COLOR_NORMAL=
-   PORTAGE_COLOR_BRACKET=
+   PORTAGE_COLOR_QAWARN=
+   PORTAGE_COLOR_WARN=
 }
 
 __set_colors() {
@@ -403,12 +407,16 @@ __set_colors() {
if [ -n "${PORTAGE_COLORMAP}" ] ; then
eval ${PORTAGE_COLORMAP}
else
-   PORTAGE_COLOR_GOOD=$'\e[32;01m'
-   PORTAGE_COLOR_WARN=$'\e[33;01m'
PORTAGE_COLOR_BAD=$'\e[31;01m'
-   PORTAGE_COLOR_HILITE=$'\e[36;01m'
PORTAGE_COLOR_BRACKET=$'\e[34;01m'
+   PORTAGE_COLOR_ERR=$'\e[31;01m'
+   PORTAGE_COLOR_GOOD=$'\e[32;01m'
+   PORTAGE_COLOR_HILITE=$'\e[36;01m'
+   PORTAGE_COLOR_INFO=$'\e[32m'
+   PORTAGE_COLOR_LOG=$'\e[32;01m'
PORTAGE_COLOR_NORMAL=$'\e[0m'
+   PORTAGE_COLOR_QAWARN=$'\e[33m'
+   PORTAGE_COLOR_WARN=$'\e[33;01m'
fi
 }
 

diff --git a/bin/save-ebuild-env.sh b/bin/save-ebuild-env.sh
index 8d2ec67ed..98808814b 100644
--- a/bin/save-ebuild-env.sh
+++ b/bin/save-ebuild-env.sh
@@ -102,8 +102,10 @@ __save_ebuild_env() {
LAST_E_CMD LAST_E_LEN LD_PRELOAD MISC_FUNCTIONS_ARGS MOPREFIX \
NOCOLOR PKGDIR PKGUSE PKG_LOGDIR PKG_TMPDIR \
PORTAGE_BASHRC_FILES PORTAGE_BASHRCS_SOURCED \
-   PORTAGE_COLOR_BAD PORTAGE_COLOR_BRACKET PORTAGE_COLOR_GOOD \
-   PORTAGE_COLOR_HILITE PORTAGE_COLOR_NORMAL PORTAGE_COLOR_WARN \
+   PORTAGE_COLOR_BAD PORTAGE_COLOR_BRACKET PORTAGE_COLOR_ERR \
+   PORTAGE_COLOR_GOOD PORTAGE_COLOR_HILITE PORTAGE_COLOR_INFO \
+  

[gentoo-commits] proj/portage:master commit in: lib/portage/, bin/

2021-01-18 Thread Zac Medico
commit: fb40f65ddd7635f98a2e0b14a8914697635896d4
Author: Zac Medico  gentoo  org>
AuthorDate: Tue Jan 19 07:07:57 2021 +
Commit: Zac Medico  gentoo  org>
CommitDate: Tue Jan 19 07:17:19 2021 +
URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=fb40f65d

bin: misc pylint fixes

Signed-off-by: Zac Medico  gentoo.org>

 bin/clean_locks |  5 +++--
 bin/dispatch-conf   | 17 ++---
 bin/ebuild  |  4 +---
 bin/egencache   |  6 +++---
 bin/emerge  | 13 -
 bin/glsa-check  |  5 +++--
 bin/portageq| 18 +-
 bin/quickpkg| 10 +-
 bin/regenworld  |  6 +++---
 lib/portage/__init__.py |  3 ++-
 10 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/bin/clean_locks b/bin/clean_locks
index d1f296065..e5765fd7e 100755
--- a/bin/clean_locks
+++ b/bin/clean_locks
@@ -1,8 +1,9 @@
 #!/usr/bin/python -b
-# Copyright 1999-2020 Gentoo Authors
+# Copyright 1999-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
-import sys, errno
+import errno
+import sys
 from os import path as osp
 if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 
".portage_not_installed")):
sys.path.insert(0, 
osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "lib"))

diff --git a/bin/dispatch-conf b/bin/dispatch-conf
index fa047244a..0fdfbaa81 100755
--- a/bin/dispatch-conf
+++ b/bin/dispatch-conf
@@ -1,5 +1,5 @@
 #!/usr/bin/python -b
-# Copyright 1999-2020 Gentoo Authors
+# Copyright 1999-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 #
@@ -16,10 +16,17 @@ import io
 import re
 import subprocess
 import sys
+import termios
+import tty
 
 from stat import ST_GID, ST_MODE, ST_UID
 from random import random
 
+try:
+   import curses
+except ImportError:
+   curses = None
+
 from os import path as osp
 if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), 
".portage_not_installed")):
sys.path.insert(0, 
osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "lib"))
@@ -454,7 +461,6 @@ class dispatch:
 def getch ():
 # from ASPN - Danny Yoo
 #
-import tty, termios
 
 fd = sys.stdin.fileno()
 old_settings = termios.tcgetattr(fd)
@@ -466,8 +472,7 @@ def getch ():
 return ch
 
 def clear_screen():
-try:
-import curses
+if curses is not None:
 try:
 curses.setupterm()
 sys.stdout.write(_unicode_decode(curses.tigetstr("clear")))
@@ -475,8 +480,6 @@ def clear_screen():
 return
 except curses.error:
 pass
-except ImportError:
-pass
 os.system("clear 2>/dev/null")
 
 shell = os.environ.get("SHELL")
@@ -503,7 +506,7 @@ def usage(argv):
 for x in sys.argv:
 if x in ('-h', '--help'):
 usage(sys.argv)
-elif x in ('--version'):
+elif x in ('--version',):
 print("Portage", portage.VERSION)
 sys.exit(os.EX_OK)
 

diff --git a/bin/ebuild b/bin/ebuild
index 09f7f839b..0a2b13a13 100755
--- a/bin/ebuild
+++ b/bin/ebuild
@@ -1,5 +1,5 @@
 #!/usr/bin/python -b
-# Copyright 1999-2020 Gentoo Authors
+# Copyright 1999-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 import argparse
@@ -46,7 +46,6 @@ portage._internal_caller = True
 from portage import os
 from portage import _encodings
 from portage import _shell_quote
-from portage import _unicode_decode
 from portage import _unicode_encode
 from portage.const import VDB_PATH
 from portage.exception import PermissionDenied, PortageKeyError, \
@@ -111,7 +110,6 @@ if debug:
 
 # do this _after_ 'import portage' to prevent unnecessary tracing
 if debug and "python-trace" in portage.features:
-   import portage.debug
portage.debug.set_trace(True)
 
 if not opts.color == 'y' and \

diff --git a/bin/egencache b/bin/egencache
index 4ee63edad..9b6df2e7d 100755
--- a/bin/egencache
+++ b/bin/egencache
@@ -1,5 +1,5 @@
 #!/usr/bin/python -b
-# Copyright 2009-2020 Gentoo Authors
+# Copyright 2009-2021 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 # unicode_literals for compat with TextIOWrapper in Python 2
@@ -49,7 +49,6 @@ if 
osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".porta
 import portage
 portage._internal_caller = True
 from portage import os, _encodings, _unicode_encode, _unicode_decode
-from _emerge.MetadataRegen import MetadataRegen
 from portage.cache.cache_errors import CacheError, StatCollision
 from portage.cache.index.pkg_desc_index import pkg_desc_index_line_format, 
pkg_desc_index_line_read
 from portage.const import TIMESTAMP_FORMAT
@@ -65,6 +64,7 @@ from portage.util.changelog import ChangeLogTypeSort
 from portage import cpv_getkey
 from portage.dep import Atom, isjustname
 from portage.versions import vercmp
+from 

[gentoo-commits] proj/portage:master commit in: lib/portage/, bin/

2019-01-22 Thread Zac Medico
commit: 82e86efb503a23588b6b8e4351427cc3fca27de3
Author: Arfrever Frehtes Taifersar Arahesis  Apache  Org>
AuthorDate: Mon Jan 21 16:14:03 2019 +
Commit: Zac Medico  gentoo  org>
CommitDate: Wed Jan 23 04:47:29 2019 +
URL:https://gitweb.gentoo.org/proj/portage.git/commit/?id=82e86efb

pid-sandbox: run pid-ns-init as root (bug 675868)

Drop permissions only for subprocess of pid-ns-init but not pid-ns-init
itself. With FEATURES="pid-sandbox userpriv", pid-ns-init should be
run with unchanged permissions (usually UID=0, GID=0).

Bug: https://bugs.gentoo.org/675868
Signed-off-by: Arfrever Frehtes Taifersar Arahesis  Apache.Org>
Signed-off-by: Zac Medico  gentoo.org>

 bin/pid-ns-init| 49 ++---
 lib/portage/process.py | 12 ++--
 2 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/bin/pid-ns-init b/bin/pid-ns-init
index 76ae8de75..f01d69fc2 100644
--- a/bin/pid-ns-init
+++ b/bin/pid-ns-init
@@ -11,21 +11,6 @@ import subprocess
 import sys
 
 
-if sys.version_info.major < 3 or platform.python_implementation() != 'CPython':
-   def signal_disposition_preexec():
-   for signum in (
-   signal.SIGHUP,
-   signal.SIGINT,
-   signal.SIGPIPE,
-   signal.SIGQUIT,
-   signal.SIGTERM,
-   ):
-   signal.signal(signum, signal.SIG_DFL)
-else:
-   # CPython >= 3 subprocess.Popen handles this internally.
-   signal_disposition_preexec = None
-
-
 KILL_SIGNALS = (
signal.SIGINT,
signal.SIGTERM,
@@ -41,9 +26,31 @@ def forward_kill_signal(pid, signum, frame):
os.kill(pid, signum)
 
 
+def preexec_fn(uid, gid, groups, umask):
+   if gid is not None:
+   os.setgid(gid)
+   if groups is not None:
+   os.setgroups(groups)
+   if uid is not None:
+   os.setuid(uid)
+   if umask is not None:
+   os.umask(umask)
+
+   # CPython >= 3 subprocess.Popen handles this internally.
+   if sys.version_info.major < 3 or platform.python_implementation() != 
'CPython':
+   for signum in (
+   signal.SIGHUP,
+   signal.SIGINT,
+   signal.SIGPIPE,
+   signal.SIGQUIT,
+   signal.SIGTERM,
+   ):
+   signal.signal(signum, signal.SIG_DFL)
+
+
 def main(argv):
if len(argv) < 2:
-   return 'Usage: {}  or   
 [arg]..'.format(argv[0])
+   return 'Usage: {}  or
[arg]..'.format(argv[0])
 
if len(argv) == 2:
# The child process is init (pid 1) in a child pid namespace, 
and
@@ -55,16 +62,20 @@ def main(argv):
proc = None
else:
# The current process is init (pid 1) in a child pid namespace.
-   pass_fds, binary, args = tuple(int(fd) for fd in 
argv[1].split(',')), argv[2], argv[3:]
+   uid, gid, groups, umask, pass_fds, binary, args = argv[1], 
argv[2], argv[3], argv[4], tuple(int(fd) for fd in argv[5].split(',')), 
argv[6], argv[7:]
+   uid = int(uid) if uid else None
+   gid = int(gid) if gid else None
+   groups = tuple(int(group) for group in groups.split(',')) if 
groups else None
+   umask = int(umask) if umask else None
 
popen_kwargs = {}
+   popen_kwargs['preexec_fn'] = functools.partial(preexec_fn, uid, 
gid, groups, umask)
if sys.version_info.major > 2:
popen_kwargs['pass_fds'] = pass_fds
# Isolate parent process from process group SIGSTOP (bug 675870)
setsid = True
os.setsid()
-   proc = subprocess.Popen(args, executable=binary,
-   preexec_fn=signal_disposition_preexec, **popen_kwargs)
+   proc = subprocess.Popen(args, executable=binary, **popen_kwargs)
main_child_pid = proc.pid
 
# If setsid has been called, use kill(0, signum) to

diff --git a/lib/portage/process.py b/lib/portage/process.py
index dd3d58ddc..0dba55de3 100644
--- a/lib/portage/process.py
+++ b/lib/portage/process.py
@@ -1,5 +1,5 @@
 # portage.py -- core Portage functionality
-# Copyright 1998-2018 Gentoo Authors
+# Copyright 1998-2019 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 
@@ -467,7 +467,7 @@ def _exec(binary, mycommand, opt_name, fd_pipes,
@param gid: Group ID to run the process under
@type gid: Integer
@param groups: Groups the Process should be in.
-   @type groups: Integer
+   @type groups: List
@param uid: User ID to run the process under
@type uid: Integer
@param umask: an int representing a unix umask (see man chmod