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.VServer.start(self, True)
56 else: os.waitpid(child_pid, 0)
57 else: logger.log('%s: not starting, is not enabled' % self.name)
60 logger.log('%s: stopping' % self.name)
61 vserver.VServer.stop(self)
62 # make sure we always make the syscalls when setting resource limits
63 self.vm_running = True
65 def set_resources(self):
66 """Set the resource limits of sliver <self.name>."""
68 disk_max_KiB = self.rspec['nm_disk_quota']
69 logger.log('%s: setting max disk usage to %d KiB' %
70 (self.name, disk_max_KiB))
71 try: # don't let slivers over quota escape other limits
72 if not self.disk_limit_has_been_set:
73 self.vm_running = False
74 logger.log('%s: computing disk usage' % self.name)
76 # even if set_disklimit() triggers an exception,
77 # the kernel probably knows the disk usage
78 self.disk_limit_has_been_set = True
79 vserver.VServer.set_disklimit(self, disk_max_KiB)
80 self.vm_running = True
81 except OSError: logger.log_exc()
84 bw_fields = ['nm_net_min_rate', 'nm_net_max_rate',
85 'nm_net_exempt_min_rate', 'nm_net_exempt_max_rate',
87 args = tuple(map(self.rspec.__getitem__, bw_fields))
88 logger.log('%s: setting bw share to %d' % (self.name, args[-1]))
89 logger.log('%s: setting bw limits to %s bps' % (self.name, args[:-1]))
90 self.set_bwlimit(*args)
92 # cpu limits / remote login
93 cpu_guaranteed_shares = self.rspec['nm_cpu_guaranteed_share']
94 cpu_shares = self.rspec['nm_cpu_share']
95 if self.rspec['nm_enabled']:
96 if cpu_guaranteed_shares > 0:
97 logger.log('%s: setting cpu share to %d%% guaranteed' %
98 (self.name, cpu_guaranteed_shares/10.0))
99 self.set_sched_config(cpu_guaranteed_shares,
100 vserver.SCHED_CPU_GUARANTEED)
102 logger.log('%s: setting cpu share to %d' %
103 (self.name, cpu_shares))
104 self.set_sched_config(cpu_shares, 0)
106 # tell vsh to disable remote login by setting CPULIMIT to 0
107 logger.log('%s: disabling remote login' % self.name)
108 self.set_sched_config(0, 0)