-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser_daemon.py
executable file
·78 lines (62 loc) · 1.9 KB
/
user_daemon.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
#!/usr/bin/env python
import signal
import sys
import threading
sys.path.append('/gravel/pkg/gravel-common')
import gravelrpc
import os
import cmd_util
import userns
def signal_exit(*things):
if worker.exiting:
print 'force exit'
os._exit(1)
else:
worker.exiting = True
print 'exiting...'
worker.exit()
print 'exit.'
os._exit(1)
class Handler(gravelrpc.RPCHandler):
allow_fd_passing = True
def method_start_user(self, uid):
worker.start_user(uid)
def method_stop_user(self, uid):
worker.stop_user(uid)
def method_exit(self):
worker.exit()
def method_attach(self, uid, cmd, _fds):
fd0, fd1, fd2 = _fds
worker.attach(uid, cmd, fd0, fd1, fd2)
class Worker(object):
def __init__(self):
signal.signal(signal.SIGTERM, signal_exit)
signal.signal(signal.SIGINT, signal_exit)
self.running = {}
self.lock = threading.RLock()
self.exiting = False
def start_user(self, uid):
with self.lock:
if uid not in self.running:
self.running[uid] = MyUserNS(uid)
self.running[uid].start()
def exit(self):
with self.lock:
for uid in self.running.keys():
self.stop_user(uid)
def stop_user(self, uid):
with self.lock:
userns = self.running[uid]
del self.running[uid]
userns.stop()
def attach(self, uid, cmd, fd0, fd1, fd2):
self.running[uid].attach(cmd, stdin=fd0, stdout=fd1, stderr=fd2)
class MyUserNS(userns.UserNS):
def _setup_more_fs(self):
init_file = self.dir + '/etc/init.sh'
open(init_file, 'w').close()
os.chmod(init_file, 0o755)
cmd_util.run_hooks('/gravel/pkg/gravel-userd/setupfs.d', [str(self.uid), self.dir])
if __name__ == '__main__':
worker = Worker()
Handler.main('userd')