class VirtualMachine: trace = 0 def __init__ (self, **kw): # args={}, pid=0, ports=[]): # , server=None): self.args = kw self.ip = kw.pop ("ip", 0) # IP address - this or one of the following 4 ports must be nonzero and fall into the ranges self.rdpport = kw.pop ("rdpport", 0) # specificed for each - eg, rdpport must fall into rdprange or rdphighrange self.serport = kw.pop ("serport", 0) # 2 of 4 self.monport = kw.pop ("monport", 0) # 3 of 4 self.vncport = kw.pop ("vncport", 0) # 4 of 4 self.m = kw.pop ("m", 128) # Memory / RAM parm to KVM self.mname = kw.pop ("mname", '') # text-base machine name - displayed w/spacify, symlinked, etc self.admin = kw.pop ("admin", '') # link to web admin or dev admin to show in vPanel for this vm self.dev = kw.pop ("dev", '') # link to dev instance to show in vPanel for this vm self.links = kw.pop ("links", '') # add'l link or csv list of links to show in vPanel for this vm self.run = kw.pop ("run", 0) # bool - run this vm at bootup / restart self.sandbox = kw.pop ("sandbox", 0) # bool - sandbox behavior, run w/'snapshot', restart every n minutes (via cron). self.permanent = kw.pop ("permanent", 0) # bool - permanent behavior, run at startup and try to always keep running (semantics on fault TBD). #self.parms = kw.pop ("parms", '') daemon, tablet, hda, hdb, hdc, parms? #addArgs (self, kw, False) # could catch any of the above leftovers - or just set to extra_parms.. extra_parms = kw self.up = False self.ports = [] # list of open ports - for live vm only! (up==True) self.pid = 0 # program id self.mid = 0 # machine id - dirname: ip, 'external' rdp, vnc, telnet port, etc self.sid = sid0 # secure id - hash of mid - start at sid0 self.wd = 0 # watch descriptor, for iNotify changes to parms or status - self.images = noimagelist self.set_mid_and_ports() ''' self.imagesz = (0,0) self.w = 640 # provide fallback defaults to avoid exceptions self.h = 480 self.init (args, pid, ports) def init (self, args={}, pid=0, ports=[]): if self.trace: print 'VM init:', pid, ports, self.up, args, if args: # its from the args - either running or not addArgs (self, args, False) else: # it's a live instance, init fm the pid/ports ''' def update (self, pid, ports): # it's a live vm, update accordingly self.up = True self.pid = pid self.ports = ports for p in ports: if p in serialRange: assert self.serport == p if p in monRange or p in monHighRange: assert self.monport == p if p in vncRange or p in vncHighRange: assert self.vncport == p if p in rdpRange or p in rdpHighRange: assert self.rdpport == p # assert no overlap! if p > monBase: # It has a mon_port, so it must be an ip-based variable port, so extract the ip assert self.ip == p % 1000 #self.set_mid() def set_mid_and_ports (self): # called at init from kvm_monitor import Monitor # import loop kluge #mid = self.mid # for assert if self.ip: self.ip = int (self.ip) # normalize self.dirname = `self.ip` if not self.up: if not self.monport: self.monport = self.ip + monBase if not self.vncport: self.vncport = self.ip + vncBase elif self.rdpport: self.rdpport = int (self.rdpport) self.dirname = `self.rdpport` elif self.vncport: self.vncport = int (self.vncport) self.dirname = `self.vncport` #elif self.mname: # self.dirname=self.mname else: raise 'Unknown vm dirname / mid!' + `self.ports` self.mid = self.dirname # may cause probs with mname.. self.sid = hashlib.md5 (self.mid).digest() # secure id - hash of mid #self.wd = inotifyx.add_watch (nd, self.dirname, mask) #self.wd = inotify.add_watch (self.dirname) if self.monport: self.monitor = Monitor() if self.trace: print 'end:', self.up, self.mid, self.mname #if mid: assert mid == self.mid # be sure it doesn't change! def __unicode__ (self): return '%s (%s)' % (self.mname, self.mid) def __repr__ (self): return u'VirtualMachine instance: ' + self.__unicode__() def screengrab (self): #if self.up: w,h = server.screengrab (self) # now handles down/noimg 5/8/9 jjw #else: # w,h = 0,0 self.w = w self.h = h return w,h def send (self, msg): m = self.monitor.connect (port=self.monport) if self.trace: print 'vm.send:', m, self.monport, msg if m: rslt = m.sendandclean (msg) if self.trace: print 'vm send rslt:', len (rslt), rslt m.disconnect() else: rslt = 'VM Monitor is DOWN.' return rslt def msend (self, msgs): # multiple send / return lists m = self.monitor.connect (port=self.monport) if self.trace: print 'vm msend:', m, self.monport, msgs rslt = [] if m: for msg in msgs: rslt += [m.sendandclean (msg)] m.disconnect() else: for msg in msgs: rslt += ['VM Monitor is DOWN.'] if self.trace: print 'vm msend rslt:', len (rslt), rslt return rslt def sendguest (self, s): m = self.monitor.connect (port=self.monport) if self.trace: print 'vm.sendguest:', m, self.monport, s, self.monitor.is_connected() if m: for line in s.splitlines(): if line: if line.startswith ('sendkey'): # allow sending of indiv chars to prep for script lines m.sendandclean (line) else: m.sendinstance (line) else: sleep (1) # pause on blank line! rslt = 'Sent to %s' % self.mname m.disconnect() #m.set_debuglevel(0) else: rslt = 'VM Monitor is DOWN.' return rslt def sendguestfile (self, fname): if not fname: return 'No File to send' f = open (fname) s = f.read() return self.sendguest (s) def asHtml (self): return server.asHtml (self.pid) def asDict (self): # asObject? asAttrs? return self.__dict__ def render (self, template): # for rdp_link, vnc_link, etc - was "mergeTemplate" chged 4/10 JJW return template % self.asDict()
class LocalVM (VirtualMachineBase): def __init__ (self, **kw): VirtualMachineBase.__init__ (self, **kw) #self.__dict__.update (kw) self.set_mid_and_ports() ''' self.imagesz = (0,0) self.w = 640 # provide fallback defaults to avoid exceptions self.h = 480 self.init (args, pid, ports) def init (self, args={}, pid=0, ports=[]): if self.trace: print 'VM init:', pid, ports, self.up, args, if args: # its from the args - either running or not addArgs (self, args, False) else: # it's a live instance, init fm the pid/ports ''' def update (self, pid, ports): # it's a live vm, update accordingly self.up = True self.pid = pid self.ports = ports for p in ports: if p in settings.serialRange: assert self.serport == p if p in settings.monRange or p in settings.monHighRange: assert self.monport == p if p in settings.vncRange or p in settings.vncHighRange: assert self.vncport == p if p in settings.rdpRange or p in settings.rdpHighRange: assert self.rdpport == p # assert no overlap! if p > settings.monBase: # It has a mon_port, so it must be an ip-based variable port, so extract the ip assert self.ip == p % 1000 #self.set_mid() def set_mid_and_ports (self): # called at init #mid = self.mid # for assert if self.ip: self.ip = int (self.ip) # normalize self.dirname = `self.ip` if not self.up: if not self.monport: self.monport = self.ip + settings.monBase if not self.vncport: self.vncport = self.ip + settings.vncBase elif self.rdpport: self.rdpport = int (self.rdpport) self.dirname = `self.rdpport` elif self.vncport: self.vncport = int (self.vncport) self.dirname = `self.vncport` #elif self.mname: # self.dirname=self.mname else: raise 'Unknown vm dirname / mid!' + `self.ports` self.mid = self.dirname # may cause probs with mname.. self.sid = hashlib.md5 (self.mid).hexdigest() # secure id - hash of mid #self.wd = inotifyx.add_watch (nd, self.dirname, mask) #self.wd = inotify.add_watch (self.dirname) self.monitor = Monitor (self.monport if self.monport else 0) if self.trace: print 'end:', self.up, self.mid, self.mname #if mid: assert mid == self.mid # be sure it doesn't change! def screengrab (self): #if self.up: w,h = server.screengrab (self) # now handles down/noimg 5/8/9 jjw #else: # w,h = 0,0 self.w = w self.h = h return w,h def send (self, msg): m = self.monitor.connect (port=self.monport) if self.trace: print 'vm.send:', m, self.monport, msg if m: rslt = m.sendandclean (msg) if self.trace: print 'vm send rslt:', len (rslt), rslt m.disconnect() else: rslt = 'VM Monitor is DOWN.' return rslt def msend (self, msgs): # multiple send / return lists m = self.monitor.connect (port=self.monport) if self.trace: print 'vm msend:', m, self.monport, msgs rslt = [] if m: for msg in msgs: rslt += [m.sendandclean (msg)] m.disconnect() else: for msg in msgs: rslt += ['VM Monitor is DOWN.'] if self.trace: print 'vm msend rslt:', len (rslt), rslt return rslt def sendguest (self, s): m = self.monitor.connect (port=self.monport) if self.trace: print 'vm.sendguest:', m, self.monport, s, self.monitor.is_connected() if m: for line in s.splitlines(): if line: if line.startswith ('sendkey'): # allow sending of indiv chars to prep for script lines m.sendandclean (line) else: m.sendinstance (line) else: sleep (1) # pause on blank line! rslt = 'Sent to %s' % self.mname m.disconnect() #m.set_debuglevel(0) else: rslt = 'VM Monitor is DOWN.' return rslt def sendguestfile (self, fname): if not fname: return 'No File to send' f = open (fname) s = f.read() return self.sendguest (s) def asHtml (self): return server.asHtml (self.pid) def asDict (self): # asObject? asAttrs? return self.__dict__ def render (self, template): # for rdp_link, vnc_link, etc - was "mergeTemplate" chged 4/10 JJW return template % self.asDict()
class VirtualMachine: trace = 0 def __init__ (self, args={}, pid=0, ports=[]): # , server=None): self.args = args self.ports = ports self.pid = pid # program id self.mid = 0 # machine id - dirname: ip, 'external' rdp, vnc, telnet port, etc self.sid = sid0 # secure id - hash of mid self.up = False self.rdpport = 0 self.serport = 0 self.monport = 0 self.vncport = 0 self.ip = 0 self.m = 128 self.mname = '' self.images = noimagelist self.imagesz = (0,0) self.w = 640 # provide fallback defaults to avoid exceptions self.h = 480 self.sandbox = 0 # sandbox behavior, run w/'snapshot', restart every n minutes (via cron). self.permanent = 0 # permanent behavior, run at startup and try to always keep running (semantics on fault TBD). self.run = 0 # run this vm at bootup / restart self.admin = '' # link to web admin or dev admin to show in vPanel for this vm self.dev = '' # link to dev instance to show in vPanel for this vm self.links = '' # add'l link or csv list of links to show in vPanel for this vm self.init (args, pid, ports) def init (self, args={}, pid=0, ports=[]): from kvm_monitor import Monitor # import loop kluge if self.trace: print 'VM init:', pid, ports, self.up, args, if args: # its from the args - either running or not addArgs (self, args, False) else: # it's a live instance, init fm the pid/ports self.up = True for p in ports: if p in serialRange: self.serport = p if p in monRange or p in monHighRange: self.monport = p if p in vncRange or p in vncHighRange: self.vncport = p if p in rdpRange or p in rdpHighRange: self.rdpport = p # assert no overlap! if p > 20000: # then it's an ip-based variable port, so extract ip self.ip = p % 1000 if self.ip: self.ip = int (self.ip) # normalize self.dirname = `self.ip` if not self.up: if not self.monport: self.monport = self.ip + monBase if not self.vncport: self.vncport = self.ip + vncBase elif self.rdpport: self.rdpport = int (self.rdpport) self.dirname = `self.rdpport` elif self.vncport: self.vncport = int (self.vncport) self.dirname = `self.vncport` elif self.mname: self.dirname=self.mname else: raise 'Unknown vm dirname / mid!' + `self.ports` self.mid = self.dirname # may cause probs with mname.. self.sid = hashlib.md5 (self.mid).digest() # secure id - hash of mid if self.monport: self.monitor = Monitor() if self.trace: print 'end:', self.up, self.mid, self.mname def __unicode__ (self): return '%s (%s)' % (self.mname, self.mid) def __repr__ (self): return u'VirtualMachine instance: ' + self.__unicode__() def screengrab (self): #if self.up: w,h = server.screengrab (self) # now handles down/noimg 5/8/9 jjw #else: # w,h = 0,0 self.w = w self.h = h return w,h def send (self, msg): m = self.monitor.connect (port=self.monport) if self.trace: print 'vm.send:', m, self.monport, msg if m: rslt = m.sendandclean (msg) if self.trace: print 'vm send rslt:', len (rslt), rslt m.disconnect() else: rslt = 'VM Monitor is DOWN.' return rslt def msend (self, msgs): # multiple send / return lists m = self.monitor.connect (port=self.monport) if self.trace: print 'vm msend:', m, self.monport, msgs rslt = [] if m: for msg in msgs: rslt += [m.sendandclean (msg)] m.disconnect() else: for msg in msgs: rslt += ['VM Monitor is DOWN.'] if self.trace: print 'vm msend rslt:', len (rslt), rslt return rslt def sendguest (self, s): m = self.monitor.connect (port=self.monport) if self.trace: print 'vm.sendguest:', m, self.monport, s, self.monitor.is_connected() if m: for line in s.splitlines(): if line: if line.startswith ('sendkey'): # allow sending of indiv chars to prep for script lines m.sendandclean (line) else: m.sendinstance (line) else: sleep (1) # pause on blank line! rslt = 'Sent to %s' % self.mname m.disconnect() #m.set_debuglevel(0) else: rslt = 'VM Monitor is DOWN.' return rslt def sendguestfile (self, fname): if not fname: return 'No File to send' f = open (fname) s = f.read() return self.sendguest (s) def asHtml (self): return server.asHtml (self.pid) def asDict (self): # asObject? asAttrs? return self.__dict__ # shouldn't this be called 'render'?! jjw 12/22/07 def mergeTemplate (self, template): # for rdp_link, vnc_link, etc return template % self.asDict()