From 2dee827ad9edd2f7521ac10f62c72956df918e7d Mon Sep 17 00:00:00 2001 From: Eric Price Date: Tue, 9 Oct 2007 22:08:20 -0400 Subject: [PATCH] Add support for (A) modifying VM names, memory, disksize (B) transferring ownership, hostname Has issues with multiple disks/nics because of current interface. (tabbott is the real author here) svn path=/trunk/web/; revision=161 --- templates/getafsgroups.py | 74 +++++++++++++++++++++++++++++++++++++++++++ templates/info.tmpl | 7 +++-- templates/main.py | 76 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 templates/getafsgroups.py diff --git a/templates/getafsgroups.py b/templates/getafsgroups.py new file mode 100644 index 0000000..0567efe --- /dev/null +++ b/templates/getafsgroups.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +import pprint +import subprocess + +# import ldap +# l = ldap.open("W92-130-LDAP-2.mit.edu") +# # ldap.mit.edu is 1/2 broken right now so we're going to the working backend +# l.simple_bind_s("", "") + +# def getLdapGroups(user): +# """ +# getLdapGroups(user): returns a generator for the list of LDAP groups containing user +# """ +# for user_data in l.search_s("ou=affiliates,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "uid=" + user, []): +# for group_data in l.search_s("ou=groups,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "uniqueMember="+user_data[0], ['cn']): +# yield group_data[1]['cn'][0] + +# def checkLdapGroups(user, group): +# """ +# checkLdapGroups(user, group): returns True if and only if user is in LDAP group group +# """ +# for result_data in l.search_s("ou=affiliates,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "uid=" + user, []): +# if l.search_s("ou=groups,dc=mit,dc=edu", ldap.SCOPE_ONELEVEL, "(&(cn=" + group + ")(uniqueMember="+result_data[0] + "))", []) != []: +# return True +# return False + +def checkAfsGroup(user, group, cell): + """ + checkAfsGroup(user, group) returns True if and only if user is in AFS group group in cell cell + """ + print user, group + p = subprocess.Popen(["pts", "membership", group, '-c', cell], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p2 = subprocess.Popen(["grep", "-v", "^Members"], stdin=p.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if p2.wait(): + return False + for member in p2.stdout.read().split(): + if member == user: + return True + return False + +def checkLockerOwner(user, locker): + """ + checkLockerOwner(user, locker) returns True if and only if user administers locker + """ + p = subprocess.Popen(["fs", "whichcell", "/mit/" + locker], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if (p.wait()): + return False + cell = p.stdout.read().split()[-1][1:-1] + p = subprocess.Popen(["fs", "listacl", "/mit/" + locker], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p2 = subprocess.Popen(["grep", "^ .* rlidwka$"], stdin=p.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if (p2.wait()): + return False + for line in p2.stdout.read().split('\n'): + entry = line.split() + if entry == [] or entry[0] == "Negative": + break + if entry[1] == "rlidwka": + if entry[0] == user or (entry[0][0:6] == "system" and checkAfsGroup(user, entry[0], cell)): + return True + return False + + +if __name__ == "__main__": +# print list(getldapgroups("tabbott")) + print checkAfsGroup("tabbott", "system:debathena", 'athena.mit.edu') + print checkAfsGroup("tabbott", "system:debathena", 'sipb.mit.edu') + print checkAfsGroup("tabbott", "system:debathena-root", 'athena.mit.edu') + print checkAfsGroup("tabbott", "system:hmmt-request", 'athena.mit.edu') + print checkLockerOwner("tabbott", "tabbott") + print checkLockerOwner("tabbott", "debathena") + print checkLockerOwner("tabbott", "sipb") + print checkLockerOwner("tabbott", "lsc") + print checkLockerOwner("tabbott", "scripts") + print checkLockerOwner("ecprice", "hmmt") diff --git a/templates/info.tmpl b/templates/info.tmpl index ca98ff9..ca7d107 100644 --- a/templates/info.tmpl +++ b/templates/info.tmpl @@ -62,10 +62,13 @@ Info on $machine.name
- + + + #if $machine.nics - + + #end if #if not $on diff --git a/templates/main.py b/templates/main.py index ccef044..e5dae26 100755 --- a/templates/main.py +++ b/templates/main.py @@ -13,6 +13,7 @@ import sha import hmac import datetime import StringIO +import getafsgroups sys.stderr = StringIO.StringIO() sys.path.append('/home/ecprice/.local/lib/python2.5/site-packages') @@ -117,7 +118,7 @@ def haveAccess(user, machine): """Return whether a user has access to a machine""" if user.username == 'moo': return True - return machine.owner == user.username + return getafsgroups.checkLockerOwner(user.username,machine.owner) def error(op, user, fields, err, emsg): """Print an error page when a CodeError occurs""" @@ -567,7 +568,7 @@ def command(user, fields): return Template(file="command.tmpl", searchList=[d, global_dict]) def testOwner(user, owner, machine=None): - if owner != user.username: + if not getafsgroups.checkLockerOwner(user.username, owner): raise InvalidInput('owner', owner, "Invalid") return owner @@ -578,10 +579,19 @@ def testContact(user, contact, machine=None): "Invalid") return contact +def testDisk(user, disksize, machine=None): + return disksize + +def testName(user, name, machine=None): + return name + def testHostname(user, hostname, machine): for nic in machine.nics: if hostname == nic.hostname: return hostname + # check if doesn't already exist + if NIC.select_by(hostname=hostname) == []: + return hostname raise InvalidInput('hostname', hostname, "Different from before") @@ -589,19 +599,59 @@ def testHostname(user, hostname, machine): def modify(user, fields): """Handler for modifying attributes of a machine.""" #XXX not written yet - machine = testMachineId(user, fields.getfirst('machine_id')) - owner = testOwner(user, fields.getfirst('owner'), machine) - contact = testContact(user, fields.getfirst('contact')) - hostname = testHostname(user, fields.getfirst('hostname'), + + transaction = ctx.current.create_transaction() + try: + machine = testMachineId(user, fields.getfirst('machine_id')) + owner = testOwner(user, fields.getfirst('owner'), machine) + contact = testContact(user, fields.getfirst('contact')) + hostname = testHostname(owner, fields.getfirst('hostname'), machine) - ram = fields.getfirst('memory') - if ram is not None: - ram = validMemory(user, ram, machine) - disk = testDisk(user, fields.getfirst('disk')) - if disk is not None: - disk = validDisk(user, disk, machine) + name = testName(user, fields.getfirst('name')) + oldname = machine.name + olddisk = {} + + memory = fields.getfirst('memory') + if memory is not None: + memory = validMemory(user, memory, machine) + if memory != machine.memory: + machine.memory = memory + + disksize = testDisk(user, fields.getfirst('disk')) + if disksize is not None: + disksize = validDisk(user, disksize, machine) + + for disk in machine.disks: + disk.size = disksize + olddisk[disk.guest_device_name] = disk.size + ctx.current.save(disk) + + # XXX all NICs get same hostname on change? Interface doesn't support more. + for nic in machine.nics: + nic.hostname = hostname + ctx.current.save(nic) + + if owner != machine.owner: + machine.owner = owner + if name != machine.name: + machine.name = name + + ctx.current.save(machine) + transaction.commit() + except: + transaction.rollback() + remctl("web", "moveregister", oldname, name) + for disk in machine.disks: + # XXX all disks get the same size on change? Interface doesn't support more. + if disk.size != olddisk[disk.guest_device_name]: + remctl("web", "lvresize", oldname, disk.guest_device_name, str(disk.size)) + if oldname != name: + remctl("web", "lvrename", oldname, disk.guest_device_name, name) + d = dict(user=user, + command="modify", + machine=machine) + return Template(file="command.tmpl", searchList=[d, global_dict]) - def help(user, fields): """Handler for help messages.""" -- 1.7.9.5
Owner:
Owner:NOTE: The Owner must the name of a locker that you administer
Contact email:
Machine Name:
Hostname:.servers.csail.mit.edu
Hostname:.servers.csail.mit.eduNOTE: The hostname must being with "Owner_".
Ram:MB (max $max_mem)