def close(self): # XXX this whole File class is a kludge, and really needs to # be gotten rid of and the useful bits moved into ISconf as part # of the refactoring to turn ISFS into ISDM # # build journal transaction message os.close(self.tmp) fbp = fbp822() parent = os.path.dirname(self.path) pathmodes = [] while True: pstat = os.stat(parent) mug = "%d:%d:%d" % (pstat.st_mode,pstat.st_uid,pstat.st_gid) pathmodes.insert(0,mug) if len(parent) == 1: assert parent == '/' break parent = os.path.dirname(parent) assert len(parent) >= 1 # XXX pathname needs to be relative to volroot msg = fbp.mkmsg('snap','', pathname=self.path, st_mode = self.st.st_mode, st_uid = self.st.st_uid, st_gid = self.st.st_gid, st_atime = self.st.st_atime, st_mtime = self.st.st_mtime, pathmodes = ','.join(pathmodes) ) debug("calling addwip") yield kernel.wait(self.volume.addwip(msg=msg,tmpfn=self.tmpfn)) self.volume.closefile(self) info("snapshot done:", self.path)
def close(self): fbp = fbp822() # XXX only support complete file overwrite for now msg = fbp.mkmsg('truncate', pathname=path,message=message,seek=self._tell) self.volume.addwip(msg) self.volume.closefile(self)
def close(self): # XXX this whole File class is a kludge, and really needs to # be gotten rid of and the useful bits moved into ISconf as part # of the refactoring to turn ISFS into ISDM # # build journal transaction message os.close(self.tmp) fbp = fbp822() parent = os.path.dirname(self.path) pathmodes = [] while True: pstat = os.stat(parent) mug = "%d:%d:%d" % (pstat.st_mode, pstat.st_uid, pstat.st_gid) pathmodes.insert(0, mug) if len(parent) == 1: assert parent == '/' break parent = os.path.dirname(parent) assert len(parent) >= 1 # XXX pathname needs to be relative to volroot msg = fbp.mkmsg('snap', '', pathname=self.path, st_mode=self.st.st_mode, st_uid=self.st.st_uid, st_gid=self.st.st_gid, st_atime=self.st.st_atime, st_mtime=self.st.st_mtime, pathmodes=','.join(pathmodes)) debug("calling addwip") yield kernel.wait(self.volume.addwip(msg=msg, tmpfn=self.tmpfn)) self.volume.closefile(self) info("snapshot done:", self.path)
def run(self): yield kernel.sigbusy debug("CLIServer running") fbp = fbp822() # set up FBP buses tocli = Bus('tocli') # process messages from client proc = kernel.spawn(self.process(transport=self.transport,outpin=tocli)) # send messages to client res = kernel.spawn(self.respond(transport=self.transport,inpin=tocli)) # merge in log messages log = kernel.spawn(self.merge(tocli,BUS.log)) # heartbeat to client kernel.spawn(self.heartbeat(transport=self.transport)) # wait for everything to quiesce yield kernel.siguntil, proc.isdone yield kernel.sigsleep, .1 while True: yield None i=0 for q in (tocli,BUS.log): if q.busy(): i+=1 continue if i == 0: break debug("telling client to exit") yield kernel.sigsleep, .1 # XXX tocli.tx(fbp.mkmsg('rc',0))
def close(self): fbp = fbp822() # XXX only support complete file overwrite for now msg = fbp.mkmsg('truncate', pathname=path, message=message, seek=self._tell) self.volume.addwip(msg) self.volume.closefile(self)
def client(transport,argv,kwopt): """ A unix-domain client of an isconf server. This client is very thin -- all the smarts are on the server side. argv is e.g. ('snap', '/tmp/foo') """ # XXX convert to use global log funcs def clierr(code,msg=''): desc = iserrno.strerror(code) if len(msg): msg = "%s: %s" % (msg, desc) else: msg = desc.strip() warn("clierr: ", msg) return code fbp = fbp822() verb = argv.pop(0) if len(argv): payload = "\n".join(argv) + "\n" else: payload = '' logname = os.environ['LOGNAME'] cwd = os.getcwd() msg = fbp.mkmsg('cmd',payload,verb=verb,logname=logname,cwd=cwd,**kwopt) # this is a blocking write... # XXX what happens here if daemon dies? debug("sending cmd") transport.write(str(msg)) debug("cmd sent") # we should get a heartbeat message from server every few seconds # XXX make this smaller, fix test case, test timeout = os.environ.get('IS_TIMEOUT_CLI',60) transport.timeout = timeout # sockfile = transport.sock.makefile('r') # stream = fbp.fromFile(sockfile,intask=False) stream = fbp.fromStream(transport,intask=False) # process one message each time through loop while True: debug("client loop") time.sleep(.1) try: msg = stream.next() except StopIteration: return clierr(iserrno.ECONNRESET) except Error822, e: return clierr(iserrno.EBADMSG,e) except Timeout: # XXX change this after logging cleaned up error("server timed out -- check /tmp/isconf.stderr and isconf.log")
def XXXbusexit(errpin,code,msg=''): desc = iserrno.strerror(code) if str or msg: msg = "%s: %s\n" % (str(msg), desc) fbp=fbp822() if msg and code: warn("busexit: ", msg) msg = "isconf: error: " + msg errpin.tx(fbp.mkmsg('stderr',msg)) errpin.tx(fbp.mkmsg('rc',code))
def write(self,data): if self.mode != 'w': raise Exception("not opened for write") tmp = tempfile.TemporaryFile() tmp.write(data) # build journal transaction message fbp = fbp822() msg = fbp.mkmsg('write',data, pathname=self.path, message=self.message, seek=self._tell, ) self.volume.addwip(msg) self._tell += len(data)
def write(self, data): if self.mode != 'w': raise Exception("not opened for write") tmp = tempfile.TemporaryFile() tmp.write(data) # build journal transaction message fbp = fbp822() msg = fbp.mkmsg( 'write', data, pathname=self.path, message=self.message, seek=self._tell, ) self.volume.addwip(msg) self._tell += len(data)
def update(self,reboot_ok=False): fbp = fbp822() if self.wip(): error("local changes not checked in") return info("checking for updates") yield kernel.wait(self.pull()) pending = self.pending() if not len(pending): info("no new updates") return for msg in pending: debug(msg['pathname'],time.time()) # XXX XXX XXX OUCH!!! using 'wait' here keeps us from # XXX XXX XXX checking return codes; execution of journal # XXX XXX XXX will always continue on error if msg.type() == 'snap': yield kernel.wait(self.updateSnap(msg)) if msg.type() == 'exec': yield kernel.wait(self.updateExec(msg)) if msg.type() == 'reboot': yield kernel.wait(self.updateReboot(msg,reboot_ok)) info("update done")
def update(self, reboot_ok=False): fbp = fbp822() if self.wip(): error("local changes not checked in") return info("checking for updates") yield kernel.wait(self.pull()) pending = self.pending() if not len(pending): info("no new updates") return for msg in pending: debug(msg['pathname'], time.time()) # XXX XXX XXX OUCH!!! using 'wait' here keeps us from # XXX XXX XXX checking return codes; execution of journal # XXX XXX XXX will always continue on error if msg.type() == 'snap': yield kernel.wait(self.updateSnap(msg)) if msg.type() == 'exec': yield kernel.wait(self.updateExec(msg)) if msg.type() == 'reboot': yield kernel.wait(self.updateReboot(msg, reboot_ok)) info("update done")
def run(self): from SocketServer import UDPServer from isconf.fbp822 import fbp822, Error822 kernel.spawn(self.puller()) kernel.spawn(self.sender()) # XXX most of the following should be broken out into a receiver() task dir = self.p.cache udpport = self.udpport debug("UDP server serving %s on port %d" % (dir,udpport)) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock = sock sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True) sock.setblocking(0) sock.bind(('',udpport)) # laddr = sock.getsockname() # localip = os.environ['HOSTNAME'] while True: yield None self.flush() yield None try: data,addr = sock.recvfrom(8192) # XXX check against addrs or nets debug("from %s: %s" % (addr,data)) factory = fbp822() msg = factory.parse(data) type = msg.type().strip() if msg.head.tuid == self.tuid: # debug("one of ours -- ignore",str(msg)) continue if not HMAC.msgck(msg): debug("HMAC failed, dropping: %s" % msg) continue if type == 'whohas': path = msg['file'] path = path.lstrip('/') fullpath = os.path.join(dir,path) fullpath = os.path.normpath(fullpath) newer = int(msg.get('newer',None)) # security checks bad=0 if fullpath != os.path.normpath(fullpath): bad += 1 if dir != os.path.commonprefix( (dir,os.path.abspath(fullpath))): print dir,os.path.commonprefix( (dir,os.path.abspath(fullpath))) bad += 2 if bad: warn("unsafe request %d from %s: %s" % ( bad,addr,fullpath)) continue if not os.path.isfile(fullpath): debug("ignoring whohas from %s: not found: %s" % (addr,fullpath)) continue if newer is not None and newer >= getmtime_int( fullpath): debug("ignoring whohas from %s: not newer: %s" % (addr,fullpath)) continue # url = "http://%s:%d/%s" % (localip,httpport,path) self.ihaveTx(path) continue if type == 'ihave': debug("gotihave:",str(msg)) ip = addr[0] yield kernel.wait(self.ihaveRx(msg,ip)) continue warn("unsupported message type from %s: %s" % (addr,type)) except socket.error: yield kernel.sigsleep, 1 continue except Exception, e: warn("%s from %s: %s" % (e,addr,str(msg))) continue
def run(self): from SocketServer import UDPServer from isconf.fbp822 import fbp822, Error822 kernel.spawn(self.puller()) kernel.spawn(self.sender()) # XXX most of the following should be broken out into a receiver() task dir = self.p.cache udpport = self.udpport debug("UDP server serving %s on port %d" % (dir, udpport)) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock = sock sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True) sock.setblocking(0) sock.bind(('', udpport)) # laddr = sock.getsockname() # localip = os.environ['HOSTNAME'] while True: yield None self.flush() yield None try: data, addr = sock.recvfrom(8192) # XXX check against addrs or nets debug("from %s: %s" % (addr, data)) factory = fbp822() msg = factory.parse(data) type = msg.type().strip() if msg.head.tuid == self.tuid: # debug("one of ours -- ignore",str(msg)) continue if not HMAC.msgck(msg): debug("HMAC failed, dropping: %s" % msg) continue if type == 'whohas': path = msg['file'] path = path.lstrip('/') fullpath = os.path.join(dir, path) fullpath = os.path.normpath(fullpath) newer = int(msg.get('newer', None)) # security checks bad = 0 if fullpath != os.path.normpath(fullpath): bad += 1 if dir != os.path.commonprefix( (dir, os.path.abspath(fullpath))): print dir, os.path.commonprefix( (dir, os.path.abspath(fullpath))) bad += 2 if bad: warn("unsafe request %d from %s: %s" % (bad, addr, fullpath)) continue if not os.path.isfile(fullpath): debug("ignoring whohas from %s: not found: %s" % (addr, fullpath)) continue if newer is not None and newer >= getmtime_int(fullpath): debug("ignoring whohas from %s: not newer: %s" % (addr, fullpath)) continue # url = "http://%s:%d/%s" % (localip,httpport,path) self.ihaveTx(path) continue if type == 'ihave': debug("gotihave:", str(msg)) ip = addr[0] yield kernel.wait(self.ihaveRx(msg, ip)) continue warn("unsupported message type from %s: %s" % (addr, type)) except socket.error: yield kernel.sigsleep, 1 continue except Exception, e: warn("%s from %s: %s" % (e, addr, str(msg))) continue