6 from config import DEFAULT_RSPEC
12 class Sliver(vserver.VServer):
13 """This class wraps vserver.VServer to make its interface closer to what we need for the Node Manager."""
18 def __init__(self, name):
19 vserver.VServer.__init__(self, name, vm_running=True)
20 self.disk_limit_has_been_set = False
21 self.rspec = DEFAULT_RSPEC.copy()
26 def create(name): logger.log_call('/usr/sbin/vuseradd', name)
29 def destroy(name): logger.log_call('/usr/sbin/vuserdel', name)
31 def configure(self, rec):
32 self.rspec.update(rec['eff_rspec'])
34 if rec['ssh_keys'] != self.ssh_keys:
35 accounts.install_ssh_keys(rec)
36 self.ssh_keys = rec['ssh_keys']
37 if rec['initscript'] != self.initscript:
38 logger.log('%s: installing initscript' % self.name)
39 def install_initscript():
40 flags = os.O_WRONLY|os.O_CREAT|os.O_TRUNC
41 fd = os.open('/etc/rc.vinit', flags, 0755)
42 os.write(fd, base64.b64decode(rec['initscript']))
44 try: self.chroot_call(install_initscript)
46 if e.errno != errno.EEXIST: logger.log_exc()
47 self.initscript = rec['initscript']
50 if self.rspec['nm_enabled']:
51 logger.log('%s: starting' % self.name)
54 # VServer.start calls fork() internally, so we don't need all of fork_as()
55 tools.close_nonstandard_fds()
56 vserver.VServer.start(self, True)
58 else: os.waitpid(child_pid, 0)
59 else: logger.log('%s: not starting, is not enabled' % self.name)
62 logger.log('%s: stopping' % self.name)
63 vserver.VServer.stop(self)
64 # make sure we always make the syscalls when setting resource limits
65 self.vm_running = True
67 def set_resources(self):
68 """Set the resource limits of sliver <self.name>."""
70 disk_max_KiB = self.rspec['nm_disk_quota']
71 logger.log('%s: setting max disk usage to %d KiB' %
72 (self.name, disk_max_KiB))
73 try: # don't let slivers over quota escape other limits
74 if not self.disk_limit_has_been_set:
75 self.vm_running = False
76 logger.log('%s: computing disk usage' % self.name)
78 # even if set_disklimit() triggers an exception,
79 # the kernel probably knows the disk usage
80 self.disk_limit_has_been_set = True
81 vserver.VServer.set_disklimit(self, disk_max_KiB)
82 self.vm_running = True
83 except OSError: logger.log_exc()
86 bw_fields = ['nm_net_min_rate', 'nm_net_max_rate',
87 'nm_net_exempt_min_rate', 'nm_net_exempt_max_rate',
89 args = tuple(map(self.rspec.__getitem__, bw_fields))
90 logger.log('%s: setting bw share to %d' % (self.name, args[-1]))
91 logger.log('%s: setting bw limits to %s bps' % (self.name, args[:-1]))
92 self.set_bwlimit(*args)
94 # cpu limits / remote login
95 cpu_guaranteed_shares = self.rspec['nm_cpu_guaranteed_share']
96 cpu_shares = self.rspec['nm_cpu_share']
97 if self.rspec['nm_enabled']:
98 if cpu_guaranteed_shares > 0:
99 logger.log('%s: setting cpu share to %d%% guaranteed' %
100 (self.name, cpu_guaranteed_shares/10.0))
101 self.set_sched_config(cpu_guaranteed_shares,
102 vserver.SCHED_CPU_GUARANTEED)
104 logger.log('%s: setting cpu share to %d' %
105 (self.name, cpu_shares))
106 self.set_sched_config(cpu_shares, 0)
108 # tell vsh to disable remote login by setting CPULIMIT to 0
109 logger.log('%s: disabling remote login' % self.name)
110 self.set_sched_config(0, 0)