1 |
--- |
2 |
pym/portage/repository/config.py | 13 +++++++--- |
3 |
pym/portage/sync/controller.py | 52 +++++++++++++++++++++++++++++++++++++++- |
4 |
2 files changed, 61 insertions(+), 4 deletions(-) |
5 |
|
6 |
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py |
7 |
index 678cc68..f45684b 100644 |
8 |
--- a/pym/portage/repository/config.py |
9 |
+++ b/pym/portage/repository/config.py |
10 |
@@ -85,7 +85,7 @@ class RepoConfig(object): |
11 |
'main_repo', 'manifest_hashes', 'masters', 'missing_repo_name', |
12 |
'name', 'portage1_profiles', 'portage1_profiles_compat', 'priority', |
13 |
'profile_formats', 'sign_commit', 'sign_manifest', 'sync_cvs_repo', |
14 |
- 'sync_type', 'sync_umask', 'sync_uri', 'thin_manifest', |
15 |
+ 'sync_type', 'sync_umask', 'sync_uri', 'sync_user', 'thin_manifest', |
16 |
'update_changelog', 'user_location', '_eapis_banned', |
17 |
'_eapis_deprecated', '_masters_orig') |
18 |
|
19 |
@@ -165,6 +165,11 @@ class RepoConfig(object): |
20 |
sync_uri = sync_uri.strip() |
21 |
self.sync_uri = sync_uri or None |
22 |
|
23 |
+ sync_user = repo_opts.get('sync-user') |
24 |
+ if sync_user is not None: |
25 |
+ sync_user = sync_user.strip() |
26 |
+ self.sync_user = sync_user or None |
27 |
+ |
28 |
auto_sync = repo_opts.get('auto-sync') |
29 |
if auto_sync is not None: |
30 |
auto_sync = auto_sync.strip().lower() |
31 |
@@ -385,6 +390,8 @@ class RepoConfig(object): |
32 |
repo_msg.append(indent + "sync-umask: " + self.sync_umask) |
33 |
if self.sync_uri: |
34 |
repo_msg.append(indent + "sync-uri: " + self.sync_uri) |
35 |
+ if self.sync_user: |
36 |
+ repo_msg.append(indent + "sync-user: " + self.sync_user) |
37 |
if self.masters: |
38 |
repo_msg.append(indent + "masters: " + " ".join(master.name for master in self.masters)) |
39 |
if self.priority is not None: |
40 |
@@ -472,7 +479,7 @@ class RepoConfigLoader(object): |
41 |
# repos.conf is allowed to override. |
42 |
for k in ('aliases', 'auto_sync', 'eclass_overrides', |
43 |
'force', 'masters', 'priority', 'sync_cvs_repo', |
44 |
- 'sync_type', 'sync_umask', 'sync_uri', |
45 |
+ 'sync_type', 'sync_umask', 'sync_uri', 'sync_user', |
46 |
): |
47 |
v = getattr(repos_conf_opts, k, None) |
48 |
if v is not None: |
49 |
@@ -923,7 +930,7 @@ class RepoConfigLoader(object): |
50 |
def config_string(self): |
51 |
str_or_int_keys = ("auto_sync", "format", "location", |
52 |
"main_repo", "priority", "sync_cvs_repo", |
53 |
- "sync_type", "sync_umask", "sync_uri") |
54 |
+ "sync_type", "sync_umask", "sync_uri", 'sync_user') |
55 |
str_tuple_keys = ("aliases", "eclass_overrides", "force") |
56 |
repo_config_tuple_keys = ("masters",) |
57 |
keys = str_or_int_keys + str_tuple_keys + repo_config_tuple_keys |
58 |
diff --git a/pym/portage/sync/controller.py b/pym/portage/sync/controller.py |
59 |
index 0e5efb6..3104524 100644 |
60 |
--- a/pym/portage/sync/controller.py |
61 |
+++ b/pym/portage/sync/controller.py |
62 |
@@ -6,6 +6,7 @@ from __future__ import print_function |
63 |
|
64 |
import sys |
65 |
import logging |
66 |
+import grp |
67 |
import pwd |
68 |
|
69 |
import portage |
70 |
@@ -193,7 +194,56 @@ class SyncManager(object): |
71 |
self.usersync_uid = None |
72 |
spawn_kwargs = {} |
73 |
spawn_kwargs["env"] = self.settings.environ() |
74 |
- if ('usersync' in self.settings.features and |
75 |
+ if repo.sync_user is not None: |
76 |
+ def get_sync_user_data(sync_user): |
77 |
+ spl = sync_user.split(':', 1) |
78 |
+ if not spl[0]: |
79 |
+ writemsg("!!! Invalid sync-user = %s\n" % sync_user, |
80 |
+ noiselevel=-1) |
81 |
+ return () |
82 |
+ |
83 |
+ user = spl[0] |
84 |
+ try: |
85 |
+ try: |
86 |
+ # maybe it's a uid? |
87 |
+ uid = int(user) |
88 |
+ except ValueError: |
89 |
+ pw = pwd.getpwnam(user) |
90 |
+ else: |
91 |
+ pw = pwd.getpwuid(uid) |
92 |
+ except KeyError: |
93 |
+ writemsg("!!! User '%s' invalid or does not exist\n" |
94 |
+ % user, noiselevel=-1) |
95 |
+ return () |
96 |
+ |
97 |
+ if len(spl) > 1: |
98 |
+ group = spl[1] |
99 |
+ try: |
100 |
+ try: |
101 |
+ # maybe it's a gid? |
102 |
+ gid = int(group) |
103 |
+ except ValueError: |
104 |
+ gp = grp.getgrnam(group) |
105 |
+ else: |
106 |
+ pw = grp.getgrgid(gid) |
107 |
+ except KeyError: |
108 |
+ writemsg("!!! Group '%s' invalid or does not exist\n" |
109 |
+ % group, noiselevel=-1) |
110 |
+ return () |
111 |
+ |
112 |
+ gr = gp.gr_gid |
113 |
+ else: |
114 |
+ gr = pw.pw_gid |
115 |
+ |
116 |
+ return (pw.pw_uid, gr, pw.pw_dir) |
117 |
+ |
118 |
+ # user or user:group |
119 |
+ (uid, gid, home) = get_sync_user_data(repo.sync_user) |
120 |
+ spawn_kwargs["uid"] = uid |
121 |
+ spawn_kwargs["gid"] = gid |
122 |
+ spawn_kwargs["groups"] = [gid] |
123 |
+ spawn_kwargs["env"]["HOME"] = home |
124 |
+ elif ('usersync' in self.settings.features and |
125 |
portage.data.secpass >= 2 and |
126 |
(st.st_uid != os.getuid() and st.st_mode & 0o700 or |
127 |
st.st_gid != os.getgid() and st.st_mode & 0o070)): |
128 |
-- |
129 |
2.2.0 |