14 from string import Template
17 libvirt.VIR_DOMAIN_NOSTATE: 'no state',
18 libvirt.VIR_DOMAIN_RUNNING: 'running',
19 libvirt.VIR_DOMAIN_BLOCKED: 'blocked on resource',
20 libvirt.VIR_DOMAIN_PAUSED: 'paused by user',
21 libvirt.VIR_DOMAIN_SHUTDOWN: 'being shut down',
22 libvirt.VIR_DOMAIN_SHUTOFF: 'shut off',
23 libvirt.VIR_DOMAIN_CRASHED: 'crashed',
26 REF_IMG_BASE_DIR = '/vservers/.lvref'
27 CON_BASE_DIR = '/vservers'
33 def getConnection(sliver_type):
34 # TODO: error checking
35 # vtype is of the form sliver.[LXC/QEMU] we need to lower case to lxc/qemu
36 vtype = sliver_type.split('.')[1].lower()
38 return connections.setdefault(uri, libvirt.open(uri))
41 ''' Helper method to get a "nice" output of the info struct for debug'''
42 [state, maxmem, mem, ncpu, cputime] = dom.info()
43 return '%s is %s, maxmem = %s, mem = %s, ncpu = %s, cputime = %s' % (dom.name(), STATES.get(state, state), maxmem, mem, ncpu, cputime)
47 class Sliver_Libvirt(accounts.Account):
49 def __init__(self, rec):
50 self.name = rec['name']
51 logger.verbose ('sliver_libvirt: %s init'%(self.name))
53 # Assume the directory with the image and config files
58 self.slice_id = rec['slice_id']
60 self.conn = getConnection(rec['type'])
63 self.dom = self.conn.lookupByName(self.name)
65 logger.verbose('sliver_libvirt: Domain %s does not exist UNEXPECTED: %s'%(self.name, sys.exc_info()[0]))
68 def start(self, delay=0):
69 ''' Just start the sliver '''
70 logger.verbose('sliver_libvirt: %s start'%(self.name))
72 # Check if it's running to avoid throwing an exception if the
73 # domain was already running, create actually means start
74 if not self.is_running():
77 logger.verbose('sliver_libvirt: sliver %s already started'%(dom.name()))
81 logger.verbose('sliver_libvirt: %s stop'%(self.name))
86 logger.verbose('sliver_libvirt: Domain %s not running UNEXPECTED: %s'%(self.name, sys.exc_info()[0]))
87 print 'sliver_libvirt: Domain %s not running UNEXPECTED: %s'%(self.name, sys.exc_info()[0])
90 ''' Return True if the domain is running '''
91 logger.verbose('sliver_libvirt: %s is_running'%self.name)
93 [state, _, _, _, _] = self.dom.info()
94 if state == libvirt.VIR_DOMAIN_RUNNING:
95 logger.verbose('sliver_libvirt: %s is RUNNING'%self.name)
98 info = debuginfo(self.dom)
99 logger.verbose('sliver_libvirt: %s is NOT RUNNING...\n%s'%(self.name, info))
102 logger.verbose('sliver_libvirt: UNEXPECTED ERROR in %s...\n%s'%(self.name, sys.exc_info[0]))
103 print 'sliver_libvirt: UNEXPECTED ERROR in %s...\n%s'%(self.name, sys.exc_info[0])
105 def configure(self, rec):
107 sliver_type = rec['type'].split('.')[1] #sliver.[lxc/qemu]
109 BASE_DIR = '/cgroup/libvirt/%s/%s/'%(sliver_type, self.name)
111 # No way through cgroups... figure out how to do that with user/dir quotas.
112 # There is no way to do quota per directory. Chown-ing would create
113 # problems as username namespaces are not yet implemented (and thus, host
114 # and containers share the same name ids
116 # Btrfs support quota per volumes
118 # It will depend on the FS selection
119 if rec.has_key('disk_max'):
120 disk_max = rec['disk_max']
125 # limit to certain number
129 if rec.has_key('memlock_hard'):
130 mem = rec['memlock_hard'] * 1024 # hard limit in bytes
131 with open(os.path.join(BASE_DIR, 'memory.limit_in_bytes'), 'w') as f:
133 if rec.has_key('memlock_soft'):
134 mem = rec['memlock_soft'] * 1024 # soft limit in bytes
135 with open(os.path.join(BASE_DIR, 'memory.soft_limit_in_bytes'), 'w') as f:
139 # Only cpu_shares until figure out how to provide limits and guarantees
141 if rec.has_key('cpu_share'):
142 cpu_share = rec['cpu_share']
143 with open(os.path.join(BASE_DIR, 'cpu.shares'), 'w') as f:
146 # Call the upper configure method (ssh keys...)
147 accounts.Account.configure(self, rec)