Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
 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)
Ejemplo n.º 4
0
    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))
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
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")
Ejemplo n.º 7
0
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))
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
 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")
Ejemplo n.º 11
0
 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")
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
    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