libvserver.py (12790B)
1 #!/usr/bin/python -tt 2 # 3 # $Id$ 4 # Copyright (C) 2008 Daniel Hokka Zakrisson 5 # vim:set ts=4 sw=4 expandtab: 6 # 7 # This program is free software; you can redistribute it and/or 8 # modify it under the terms of the GNU General Public License 9 # as published by the Free Software Foundation; either version 2 10 # of the License, or (at your option) any later version. 11 # 12 # This program is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with this program; if not, write to the Free Software 19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 21 import _libvserver 22 23 class struct: 24 _default_ = 0 25 def __init__(self, *args, **kwargs): 26 l = len(args) 27 if l > len(self._fields_): 28 raise KeyError("%s has only %d fields" % (self.__class__, 29 len(self._fields_))) 30 for i in range(0, l): 31 self.__dict__[self._fields_[i]] = args[i] 32 for i in kwargs.iterkeys(): 33 if i not in self._fields_: 34 raise KeyError("%s has no such field '%s'" % (self.__class__, 35 i)) 36 self.__dict__[i] = kwargs[i] 37 def __totuple(self): 38 return tuple(self.__dict__.get(f, self._default_) for f in self._fields_) 39 def __iter__(self): 40 return self.__totuple().__iter__() 41 def __repr__(self): 42 return repr(self.__dict__) 43 def __addsub(self, other, negator): 44 import copy 45 c = copy.deepcopy(self) 46 for i in vars(other): 47 if i in self._fields_: 48 c.__dict__[i] = (self.__dict__.get(i, self._default_) + 49 (negator * getattr(other, i))) 50 return c 51 def __add__(self, other): 52 return self.__addsub(other, 1) 53 def __sub__(self, other): 54 return self.__addsub(other, -1) 55 56 get_vci = _libvserver.vc_get_vci 57 58 class struct_ctx_flags(struct): 59 _fields_ = ["flagword", "mask"] 60 61 def ctx_create(xid, flags=None): 62 if flags is None: 63 flags = (0, 0) 64 elif not isinstance(flags, struct_ctx_flags): 65 raise TypeError("flags must be of type struct_ctx_flags") 66 return _libvserver.vc_ctx_create(xid, *flags) 67 def ctx_migrate(xid, flags=0): 68 return _libvserver.vc_ctx_migrate(xid, flags) 69 70 class struct_ctx_stat(struct): 71 _fields_ = ["usecnt", "tasks"] 72 def ctx_stat(xid): 73 return struct_ctx_stat(*_libvserver.vc_ctx_stat(xid)) 74 75 class struct_virt_stat(struct): 76 _fields_ = ["offset", "uptime", "nr_threads", "nr_running", 77 "nr_uninterruptible", "nr_onhold", "nr_forks", 78 "load0", "load1", "load2"] 79 def virt_stat(xid): 80 return struct_virt_stat(*_libvserver.vc_virt_stat(xid)) 81 82 ctx_kill = _libvserver.vc_ctx_kill 83 def get_cflags(xid): 84 return struct_ctx_flags(*_libvserver.vc_get_cflags(xid)) 85 def set_cflags(xid, flags): 86 if not isinstance(flags, struct_ctx_flags): 87 raise TypeError("flags must be of type struct_ctx_flags") 88 _libvserver.vc_set_cflags(xid, *flags) 89 90 class struct_ctx_caps(struct): 91 _fields_ = ["bcaps", "bmask", "ccaps", "cmask"] 92 def get_ccaps(xid): 93 return struct_ctx_caps(*_libvserver.vc_get_ccaps(xid)) 94 def set_ccaps(xid, caps): 95 if not isinstance(caps, struct_ctx_caps): 96 raise TypeError("caps must be of type struct_ctx_caps") 97 _libvserver.vc_set_ccaps(xid, *caps) 98 99 class struct_vx_info(struct): 100 _fields_ = ["xid", "initpid"] 101 def get_vx_info(xid): 102 return struct_vx_info(*_libvserver.vc_get_vx_info(xid)) 103 104 get_task_xid = _libvserver.vc_get_task_xid 105 wait_exit = _libvserver.vc_wait_exit 106 107 class struct_rlimit_mask(struct): 108 _fields_ = ["min", "soft", "hard"] 109 def get_rlimit_mask(xid): 110 return struct_rlimit_mask(*_libvserver.vc_get_rlimit_mask(xid)) 111 112 class struct_rlimit(struct): 113 _fields_ = ["min", "soft", "hard"] 114 _default_ = _libvserver.VC_LIM_KEEP 115 def get_rlimit(xid, resource): 116 return struct_rlimit(*_libvserver.vc_get_rlimit(xid, resource)) 117 def set_rlimit(xid, resource, limit): 118 if not isinstance(limit, struct_rlimit): 119 raise TypeError("limit must be of type struct_rlimit") 120 _libvserver.vc_set_rlimit(xid, resource, *limit) 121 122 class stuct_rlimit_stat(struct): 123 _fields_ = ["hits", "value", "minimum", "maximum"] 124 def rlimit_stat(xid, resource): 125 return struct_rlimit_stat(*_libvserver.vc_rlimit_stat(xid, resource)) 126 127 reset_minmax = _libvserver.vc_reset_minmax 128 129 get_task_nid = _libvserver.vc_get_task_nid 130 net_create = _libvserver.vc_net_create 131 net_migrate = _libvserver.vc_net_migrate 132 133 class struct_net_addr(struct): 134 _fields_ = ["vna_type", "vna_flags", "vna_prefix", "vna_parent", "ip1", 135 "ip2", "mask"] 136 137 def net_add(nid, addr): 138 if not isinstance(addr, struct_net_addr): 139 raise TypeError("addr must be of type struct_net_addr") 140 _libvserver.vc_net_add(nid, *addr) 141 142 def net_remove(nid, addr): 143 if not isinstance(addr, struct_net_addr): 144 raise TypeError("addr must be of type struct_net_addr") 145 _libvserver.vc_net_remove(nid, *addr) 146 147 class struct_net_flags(struct): 148 _fields_ = ["flagword", "mask"] 149 def get_nflags(nid): 150 return struct_net_flags(*_libvserver.vc_get_nflags(nid)) 151 def set_nflags(nid, flags): 152 if not isinstance(flags, struct_net_flags): 153 raise TypeError("flags must be of type struct_net_flags") 154 _libvserver.vc_set_nflags(nid, *flags) 155 156 class struct_net_caps(struct): 157 _fields_ = ["ncaps", "cmask"] 158 def get_ncaps(nid): 159 return struct_net_caps(*_libvserver.vc_get_ncaps(nid)) 160 def set_ncaps(nid, caps): 161 if not isinstance(caps, struct_net_caps): 162 raise TypeError("caps must be of type struct_net_caps") 163 _libvserver.vc_set_ncaps(nid, *caps) 164 165 def _vc_set_iattr(f, obj, tag, flags, mask): 166 if tag is None: 167 tag = 0 168 else: 169 mask |= _libvserver.VC_IATTR_XID 170 f(obj, tag, flags, mask) 171 def set_iattr(filename, tag=None, flags=0, mask=0): 172 _vc_set_iattr(_libvserver.vc_set_iattr, filename, tag, flags, mask) 173 def fset_iattr(fd, tag=None, flags=0, mask=0): 174 _vc_set_iattr(_libvserver.vc_fset_iattr, fd, tag, flags, mask) 175 get_iattr = lambda f: _libvserver.vc_get_iattr(f, -1) 176 fget_iattr = lambda f: _libvserver.vc_fget_iattr(f, -1) 177 178 def vhi_type(type): 179 if isinstance(type, int): 180 return type 181 else: 182 return _libvserver.__dict__["vcVHI_%s" % type] 183 def set_vhi_name(xid, type, val): 184 _libvserver.vc_set_vhi_name(xid, vhi_type(type), val) 185 def get_vhi_name(xid, type): 186 return _libvserver.vc_get_vhi_name(xid, vhi_type(type)) 187 188 enter_namespace = _libvserver.vc_enter_namespace 189 set_namespace = _libvserver.vc_set_namespace 190 get_space_mask = _libvserver.vc_get_space_mask 191 get_space_default = _libvserver.vc_get_space_default 192 193 def add_dlimit(path, tag, flags=0): 194 _libvserver.vc_add_dlimit(path, tag, flags) 195 def rem_dlimit(path, tag, flags=0): 196 _libvserver.vc_rem_dlimit(path, tag, flags) 197 class struct_ctx_dlimit(struct): 198 _fields_ = ["space_used", "space_total", "inodes_used", "inodes_total", 199 "reserved"] 200 _default_ = _libvserver.VC_CDLIM_KEEP 201 def set_dlimit(path, tag, limit, flags=0): 202 if not isinstance(limit, struct_ctx_dlimit): 203 raise TypeError("limit must be of type struct_ctx_dlimit") 204 _libvserver.vc_set_dlimit(path, tag, flags, *limit) 205 def get_dlimit(path, tag, flags=0): 206 return struct_ctx_dlimit(*_libvserver.vc_get_dlimit(path, tag, flags)) 207 208 get_task_tag = _libvserver.vc_get_task_tag 209 tag_create = _libvserver.vc_tag_create 210 tag_migrate = _libvserver.vc_tag_migrate 211 212 class struct_set_sched(struct): 213 _fields_ = ["set_mask", "fill_rate", "interval", "fill_rate2", "interval2", 214 "tokens", "tokens_min", "tokens_max", "priority_bias", 215 "cpu_id", "bucket_id"] 216 def fill_set_mask(self): 217 if "set_mask" not in self.__dict__: 218 self.set_mask = 0 219 for field in self.__dict__: 220 f = field.replace("priority", "prio").upper() 221 self.set_mask |= _libvserver.__dict__.get("VC_VXSM_" + f, 0) 222 def set_sched(xid, sched): 223 if not isinstance(sched, struct_set_sched): 224 raise TypeError("sched must be of type struct_set_sched") 225 sched.fill_set_mask() 226 _libvserver.vc_set_sched(xid, *sched) 227 def get_sched(xid, cpu_id=0, bucket_id=0): 228 return struct_set_sched(*_libvserver.vc_get_sched(xid, cpu_id, bucket_id)) 229 230 class struct_sched_info(struct): 231 _fields_ = ["cpu_id", "bucket_id", "user_msec", "sys_msec", "hold_msec", 232 "token_usec", "vavavoom"] 233 def sched_info(xid, cpu_id=-1, bucket_id=0): 234 if cpu_id == -1: 235 import os 236 ret = struct_sched_info() 237 ncpus = os.sysconf("SC_NPROCESSORS_ONLN") 238 seen = 0 239 # * 2 is to make sure we get all the processors. CPU hot-plug... 240 for cpu in range(0, ncpus * 2): 241 try: 242 ret += struct_sched_info(*_libvserver.vc_sched_info(xid, 243 cpu, 0)) 244 seen += 1 245 except: 246 pass 247 if seen == ncpus: 248 break 249 return ret 250 else: 251 return struct_sched_info(*_libvserver.vc_sched_info(xid, cpu_id, 252 bucket_id)) 253 254 set_mapping = _libvserver.vc_set_mapping 255 unset_mapping = _libvserver.vc_unset_mapping 256 257 get_badness = _libvserver.vc_get_badness 258 set_badness = _libvserver.vc_set_badness 259 260 get_insecurebcaps = _libvserver.vc_get_insecurebcaps 261 get_insecureccaps = _libvserver.vc_get_insecureccaps 262 263 isSupported = _libvserver.vc_isSupported 264 isSupportedString = _libvserver.vc_isSupportedString 265 266 getXIDType = _libvserver.vc_getXIDType 267 268 def xidopt2xid(opt, honor_static=True): 269 return _libvserver.vc_xidopt2xid(opt, honor_static) 270 def nidopt2nid(opt, honor_static=True): 271 return _libvserver.vc_nidopt2nid(opt, honor_static) 272 def tagopt2tag(opt, honor_static=True): 273 return _libvserver.vc_tagopt2tag(opt, honor_static) 274 275 # XXX: bcap, ccap, cflag, nflag, ncap could all use the same code here. 276 def text2bcap(text): 277 ret = _libvserver.vc_text2bcap(text) 278 if ret == 0: 279 raise ValueError("%s is not a valid bcap" % text) 280 return ret 281 lobcap2text = _libvserver.vc_lobcap2text 282 def bcap2list(bcaps): 283 list = [] 284 while True: 285 bcaps, text = _libvserver.vc_lobcap2text(bcaps) 286 if text is None: 287 break 288 list.append(text) 289 return ",".join(list) 290 def list2bcap(list): 291 bcaps, bmask = _libvserver.vc_list2bcap(list) 292 return struct_ctx_caps(bcaps=bcaps, bmask=bmask) 293 294 def text2ccap(text): 295 ret = _libvserver.vc_text2ccap(text) 296 if ret == 0: 297 raise ValueError("%s is not a valid ccap" % text) 298 return ret 299 loccap2text = _libvserver.vc_loccap2text 300 def ccap2list(ccaps): 301 list = [] 302 while True: 303 ccaps, text = _libvserver.vc_loccap2text(ccaps) 304 if text is None: 305 break 306 list.append(text) 307 return ",".join(list) 308 def list2ccap(list): 309 ccaps, cmask = _libvserver.vc_list2ccap(list) 310 return struct_ctx_caps(ccaps=ccaps, cmask=cmask) 311 312 def text2cflag(text): 313 ret = _libvserver.vc_text2cflag(text) 314 if ret == 0: 315 raise ValueError("%s is not a valid cflag" % text) 316 return ret 317 locflag2text = _libvserver.vc_locflag2text 318 def cflag2list(cflags): 319 list = [] 320 while True: 321 cflags, text = _libvserver.vc_locflag2text(cflags) 322 if text is None: 323 break 324 list.append(text) 325 return ",".join(list) 326 def list2cflag(list): 327 return struct_ctx_flags(*_libvserver.vc_list2cflag(list)) 328 329 def text2nflag(text): 330 ret = _libvserver.vc_text2nflag(text) 331 if ret == 0: 332 raise ValueError("%s is not a valid nflag" % text) 333 return ret 334 lonflag2text = _libvserver.vc_lonflag2text 335 def nflag2list(nflags): 336 list = [] 337 while True: 338 nflags, text = _libvserver.vc_lonflag2text(nflags) 339 if text is None: 340 break 341 list.append(text) 342 return ",".join(list) 343 def list2nflag(list): 344 return struct_net_flags(*_libvserver.vc_list2nflag(list)) 345 346 def text2ncap(text): 347 ret = _libvserver.vc_text2ncap(text) 348 if ret == 0: 349 raise ValueError("%s is not a valid ncap" % text) 350 return ret 351 loncap2text = _libvserver.vc_loncap2text 352 def ncap2list(ncaps): 353 list = [] 354 while True: 355 ncaps, text = _libvserver.vc_loncap2text(ncaps) 356 if text is None: 357 break 358 list.append(text) 359 return ",".join(list) 360 def list2ncap(list): 361 return struct_net_caps(*_libvserver.vc_list2ncap(list)) 362