-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathrun.py
executable file
·97 lines (80 loc) · 4 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python3
import argparse
# validates user input
def parser_validate(value, min = 1, max = 65535):
(container, host) = value.split('=') if '=' in value else (value, value)
(containeruid, containergid) = container.split(':') if ':' in container else (container, container)
(hostuid, hostgid) = host.split(':') if ':' in host else (host, host)
if containeruid == "":
containeruid = None
if containergid == "":
containergid = None
if hostuid == "":
hostuid = None
if hostgid == "":
hostgid = None
if containeruid is not None and not containeruid.isdigit():
raise argparse.ArgumentTypeError('Container UID "%s" is not a number' % containeruid)
elif containergid is not None and not containergid.isdigit():
raise argparse.ArgumentTypeError('Container GID "%s" is not a number' % containergid)
elif containeruid is not None and not min <= int(containeruid) <= max:
raise argparse.ArgumentTypeError('Container UID "%s" is not in range %s-%s' % (containeruid, min, max))
elif containergid is not None and not min <= int(containergid) <= max:
raise argparse.ArgumentTypeError('Container GID "%s" is not in range %s-%s' % (containergid, min, max))
if hostuid is not None and not hostuid.isdigit():
raise argparse.ArgumentTypeError('Host UID "%s" is not a number' % hostuid)
elif hostgid is not None and not hostgid.isdigit():
raise argparse.ArgumentTypeError('Host GID "%s" is not a number' % hostgid)
elif hostuid is not None and not min <= int(hostuid) <= max:
raise argparse.ArgumentTypeError('Host UID "%s" is not in range %s-%s' % (hostuid, min, max))
elif hostgid is not None and not min <= int(hostgid) <= max:
raise argparse.ArgumentTypeError('Host GID "%s" is not in range %s-%s' % (hostgid, min, max))
else:
return (
int(containeruid) if containeruid is not None else None,
int(containergid) if containergid is not None else None,
int(hostuid) if hostuid is not None else None,
int(hostgid) if hostgid is not None else None
)
# creates lxc mapping strings
def create_map(id_type, id_list):
ret = list()
# Case where no uid/gid is specified
if not id_list:
ret.append('lxc.idmap: %s 0 100000 65536' % (id_type))
return(ret)
for i, (containerid, hostid) in enumerate(id_list):
if i == 0:
ret.append('lxc.idmap: %s 0 100000 %s' % (id_type, containerid))
elif id_list[i][0] != id_list[i-1][0] + 1:
range = (id_list[i-1][0] + 1, id_list[i-1][0] + 100001, (containerid - 1) - id_list[i-1][0])
ret.append('lxc.idmap: %s %s %s %s' % (id_type, range[0], range[1], range[2]))
ret.append('lxc.idmap: %s %s %s 1' % (id_type, containerid, hostid))
if i is len(id_list) - 1:
range = (containerid + 1, containerid + 100001, 65535 - containerid)
ret.append('lxc.idmap: %s %s %s %s' % (id_type, range[0], range[1], range[2]))
return(ret)
# collect user input
parser = argparse.ArgumentParser(description='Proxmox unprivileged container to host uid:gid mapping syntax tool.')
parser.add_argument('id', nargs = '+', type = parser_validate, metavar='containeruid[:containergid][=hostuid[:hostgid]]', help = 'Container uid and optional gid to map to host. If a gid is not specified, the uid will be used for the gid value.')
parser_args = parser.parse_args()
# create sorted uid/gid lists
uid_list = sorted([(i[0], i[2]) for i in parser_args.id if i[0] is not None], key=lambda tup: tup[0])
gid_list = sorted([(i[1], i[3]) for i in parser_args.id if i[1] is not None], key=lambda tup: tup[0])
# calls function that creates mapping strings
uid_map = create_map('u', uid_list)
gid_map = create_map('g', gid_list)
# output mapping strings
print('\n# Add to /etc/pve/lxc/<container_id>.conf:')
for i in enumerate(uid_map):
print(uid_map[i[0]])
for i in enumerate(gid_map):
print(gid_map[i[0]])
if uid_list:
print('\n# Add to /etc/subuid:')
for uid in uid_list:
print('root:%s:1' % uid[1])
if gid_list:
print('\n# Add to /etc/subgid:')
for gid in gid_list:
print('root:%s:1' %gid[1])