# Copyright 2005 Princeton University
-#$Id: vserver.py,v 1.65 2007/07/31 14:36:19 dhozac Exp $
+#$Id: vserver.py,v 1.72 2007/08/02 16:01:59 dhozac Exp $
import errno
import fcntl
import subprocess
import resource
-import mountimpl
-import runcmd
-import utmp
import vserverimpl
import cpulimit, bwlimit
def __init__(self, name, directory):
self.name = name
self.dir = directory
+ self.cache = None
+ if not (os.path.isdir(self.dir) and
+ os.access(self.dir, os.R_OK | os.W_OK | os.X_OK)):
+ raise NoSuchVServer, "%s does not exist" % self.dir
def get(self, option, default = None):
try:
- f = open(os.path.join(self.dir, option), "r")
- buf = f.readline().rstrip()
- f.close()
- return buf
- except IOError, e:
+ if self.cache:
+ return self.cache[option]
+ else:
+ f = open(os.path.join(self.dir, option), "r")
+ buf = f.read().rstrip()
+ f.close()
+ return buf
+ except:
if default is not None:
return default
else:
raise KeyError, "Key %s is not set for %s" % (option, self.name)
def update(self, option, value):
+ if self.cache:
+ return
+
try:
old_umask = os.umask(0022)
filename = os.path.join(self.dir, option)
raise
def unset(self, option):
+ if self.cache:
+ return
+
try:
filename = os.path.join(self.dir, option)
os.unlink(filename)
- os.removedirs(os.path.dirname(filename))
+ try:
+ os.removedirs(os.path.dirname(filename))
+ except:
+ pass
return True
except:
return False
+ def cache_it(self):
+ self.cache = {}
+ def add_to_cache(cache, dirname, fnames):
+ for file in fnames:
+ full_name = os.path.join(dirname, file)
+ if os.path.islink(full_name):
+ fnames.remove(file)
+ elif (os.path.isfile(full_name) and
+ os.access(full_name, os.R_OK)):
+ f = open(full_name, "r")
+ cache[full_name.replace(os.path.join(self.dir, ''),
+ '')] = f.read().rstrip()
+ f.close()
+ os.path.walk(self.dir, add_to_cache, self.cache)
+
class VServer:
minimum = int(self.config.get("rlimits/%s.min"%type.lower(),VC_LIM_KEEP))
return (hard,soft,minimum)
- def set_WHITELISTED_config(self,whitelisted):
- self.config.update('whitelisted', whitelisted)
-
def set_capabilities(self, capabilities):
return vserverimpl.setbcaps(self.ctx, vserverimpl.text2bcaps(capabilities))
return None
def __do_chroot(self):
-
+ self.config.cache_it()
os.chroot(self.dir)
os.chdir("/")
# set the initial runlevel
f = open(RUNDIR + "/utmp", "w")
- utmp.set_runlevel(f, runlevel)
+ vserverimpl.setrunlevel(f, runlevel)
f.close()
# mount /proc and /dev/pts
- self.__do_mount("none", "/proc", "proc")
+ self.__do_mount("none", self.dir, "/proc", "proc")
# XXX - magic mount options
- self.__do_mount("none", "/dev/pts", "devpts", 0, "gid=5,mode=0620")
+ self.__do_mount("none", self.dir, "/dev/pts", "devpts", 0, "gid=5,mode=0620")
def __do_mount(self, *mount_args):
try:
- mountimpl.mount(*mount_args)
+ vserverimpl.mount(*mount_args)
except OSError, ex:
if ex.errno == errno.EBUSY:
# assume already mounted
state_file = open("/var/run/vservers/%s" % self.name, "w")
# use /dev/null for stdin, /var/log/boot.log for stdout/err
- try:
- os.close(0)
- os.close(1)
- except:
- pass
fd = os.open("/dev/null", os.O_RDONLY)
if fd != 0:
os.dup2(fd, 0)
# execute each init script in turn
# XXX - we don't support all scripts that vserver script does
self.__do_chcontext(state_file)
- for cmd in self.INITSCRIPTS + [None]:
+ for cmd in self.INITSCRIPTS:
try:
# enter vserver context
arg_subst = { 'runlevel': runlevel }
cmd_args = [cmd[0]] + map(lambda x: x % arg_subst,
cmd[1:])
print >>log, "executing '%s'" % " ".join(cmd_args)
- os.spawnvp(os.P_WAIT,cmd[0],*cmd_args)
+ os.spawnvp(os.P_NOWAIT,cmd[0],cmd_args)
except:
traceback.print_exc()
os._exit(1)
def create(vm_name, static = False, ctor = VServer):
- options = []
+ options = ['vuseradd']
if static:
options += ['--static']
- runcmd.run('vuseradd', options + [vm_name])
+ ret = os.spawnvp(os.P_WAIT, 'vuseradd', options + [vm_name])
+ if !os.WIFEXITED(ret) || os.WEXITSTATUS(ret) != 0:
+ out = "system command ('%s') " % options
+ if os.WIFEXITED(ret):
+ out += "failed, rc = %d" % os.WEXITSTATUS(ret)
+ else:
+ out += "killed by signal %d" % os.WTERMSIG(ret)
+ raise SystemError, out
vm_id = pwd.getpwnam(vm_name)[2]
return ctor(vm_name, vm_id)