예제 #1
0
 def __init__(self,
              host="localhost",
              trust=False,
              sshcipher=None,
              properties=None,
              identityfile=None,
              knownhostsfile=None):
     self.host = host
     self._trust = trust
     self._properties = properties if properties else []
     self._poolset = PoolSet()
     if host in ['localhost', '127.0.0.1']:
         self.command = ["zfs"]
     else:
         self.command = ["ssh", "-o", "BatchMode yes", "-a", "-x"]
         if self._trust:
             self.command.extend(["-o", "CheckHostIP no"])
             self.command.extend(["-o", "StrictHostKeyChecking no"])
         if sshcipher != None:
             self.command.extend(["-c", sshcipher])
         if identityfile != None:
             self.command.extend(["-i", identityfile])
         if knownhostsfile != None:
             self.command.extend(
                 ["-o", "UserKnownHostsFile %s" % knownhostsfile])
         self.command.extend([self.host, "zfs"])
예제 #2
0
 def __init__(self, host="localhost", trust=False, sshcipher=None):
     self.host = host
     self._trust = trust
     self._poolset = PoolSet()
     if host in ['localhost', '127.0.0.1']:
         self.command = ["zfs"]
     else:
         self.command = ["ssh", "-o", "BatchMode yes", "-a", "-x"]
         if self._trust:
             self.command.extend(["-o", "CheckHostIP no"])
             self.command.extend(["-o", "StrictHostKeyChecking no"])
         if sshcipher != None:
             self.command.extend(["-c", sshcipher])
         self.command.extend([self.host, "zfs"])
예제 #3
0
 def __init__(self,host="localhost", trust=False):
     self.host = host
     self._trust = trust
     self._poolset= PoolSet()
     if host in ['localhost','127.0.0.1']:
         self.command = ["zfs"]
     else:
         self.command = ["ssh","-o","BatchMode yes","-a","-x","-c","arcfour"]
         if self._trust:
             self.command.extend(["-o","CheckHostIP no"])
             self.command.extend(["-o","StrictHostKeyChecking no"])
         self.command.extend([self.host,"zfs"])
예제 #4
0
 def __init__(self,host="localhost", trust=False, sshcipher=None, properties=None):
     self.host = host
     self._trust = trust
     self._properties = properties if properties else []
     self._poolset= PoolSet()
     if host in ['localhost','127.0.0.1']:
         self.command = ["zfs"]
     else:
         self.command = ["ssh","-o","BatchMode yes","-a","-x"]
         if self._trust:
             self.command.extend(["-o","CheckHostIP no"])
             self.command.extend(["-o","StrictHostKeyChecking no"])
         if sshcipher != None:
             self.command.extend(["-c",sshcipher])
         self.command.extend([self.host,"zfs"])
예제 #5
0
 def __init__(self,host="localhost", trust=False, sshcipher=None, properties=None, identityfile=None, knownhostsfile=None, verbose=False):
     self.host = host
     self._trust = trust
     self._properties = properties if properties else []
     self._poolset= PoolSet()
     self.verbose = verbose
     if host in ['localhost','127.0.0.1']:
         self.command = []
     else:
         self.command = ["ssh","-o","BatchMode=yes","-a","-x"]
         if self._trust:
             self.command.extend(["-o","CheckHostIP=no"])
             self.command.extend(["-o","StrictHostKeyChecking=no"])
         if sshcipher != None:
             self.command.extend(["-c",sshcipher])
         if identityfile != None:
             self.command.extend(["-i",identityfile])
         if knownhostsfile != None:
             self.command.extend(["-o","UserKnownHostsFile=%s" % knownhostsfile])
         self.command.extend([self.host])
예제 #6
0
class ZFSConnection:
    host = None
    _poolset = None
    _dirty = True
    _trust = False
    _properties = None
    def __init__(self,host="localhost", trust=False, sshcipher=None, properties=None):
        self.host = host
        self._trust = trust
        self._properties = properties if properties else []
        self._poolset= PoolSet()
        if host in ['localhost','127.0.0.1']:
            self.command = ["zfs"]
        else:
            self.command = ["ssh","-o","BatchMode yes","-a","-x"]
            if self._trust:
                self.command.extend(["-o","CheckHostIP no"])
                self.command.extend(["-o","StrictHostKeyChecking no"])
            if sshcipher != None:
                self.command.extend(["-c",sshcipher])
            self.command.extend([self.host,"zfs"])

    def _get_poolset(self):
        if self._dirty:
            properties = [ 'creation' ] + self._properties
            stdout2 = subprocess.check_output(self.command + ["list", "-Hpr", "-o", ",".join( ['name'] + properties ), "-s", "creation", "-t", "all"])
            self._poolset.parse_zfs_r_output(stdout2,properties)
            self._dirty = False
        return self._poolset
    pools = property(_get_poolset)

    def create_dataset(self,name):
        subprocess.check_call(self.command + ["create", name])
        self._dirty = True
        return self.pools.lookup(name)

    def destroy_dataset(self, name):
        subprocess.check_call(self.command + ["destroy", name])
        self._dirty = True

    def destroy_recursively(self, name):
        subprocess.check_call(self.command + ["destroy", '-r', name])
        self._dirty = True

    def snapshot_recursively(self,name,snapshotname,properties={}):
        plist = sum( map( lambda x: ['-o', '%s=%s' % x ], properties.items() ), [] )
        subprocess.check_call(self.command + ["snapshot", "-r" ] + plist + [ "%s@%s" % (name, snapshotname)])
        self._dirty = True
    
    def send(self,name,opts=None,bufsize=-1,compression=False):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        cmd = cmd + ["send"] + opts + [name]
        p = SpecialPopen(cmd,stdin=file(os.devnull),stdout=subprocess.PIPE,bufsize=bufsize)
        return p

    def receive(self,name,pipe,opts=None,bufsize=-1,compression=False):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        cmd = cmd + ["receive"] + opts + [name]
        p = SpecialPopen(cmd,stdin=pipe,bufsize=bufsize)
        return p

    def transfer(self, dst_conn, s, d, fromsnapshot=None, showprogress=False, bufsize=-1, send_opts=None, receive_opts=None, ratelimit=-1, compression=False):
        if send_opts is None: send_opts = []
        if receive_opts is None: receive_opts = []
        
        queue_of_killables = Queue()

        if fromsnapshot: fromsnapshot=["-i",fromsnapshot]
        else: fromsnapshot = []
        sndprg = self.send(s, opts=[] + fromsnapshot + send_opts, bufsize=bufsize, compression=compression)
        sndprg_supervisor = Thread(target=lambda: queue_of_killables.put((sndprg, sndprg.wait())))
        sndprg_supervisor.start()

        if showprogress:
            try:
                        barprg = progressbar(pipe=sndprg.stdout,bufsize=bufsize,ratelimit=ratelimit)
                        barprg_supervisor = Thread(target=lambda: queue_of_killables.put((barprg, barprg.wait())))
                        barprg_supervisor.start()
                        sndprg.stdout.close()
            except OSError:
                        os.kill(sndprg.pid,15)
                        raise
        else:
            barprg = sndprg

        try:
                        rcvprg = dst_conn.receive(d,pipe=barprg.stdout,opts=["-Fu"]+receive_opts,bufsize=bufsize,compression=compression)
                        rcvprg_supervisor = Thread(target=lambda: queue_of_killables.put((rcvprg, rcvprg.wait())))
                        rcvprg_supervisor.start()
                        barprg.stdout.close()
        except OSError:
                os.kill(sndprg.pid, 15)
                if sndprg.pid != barprg.pid: os.kill(barprg.pid, 15)
                raise

        dst_conn._dirty = True
        allprocesses = set([rcvprg, sndprg]) | ( set([barprg]) if showprogress else set() )
        while allprocesses:
            diedprocess, retcode = queue_of_killables.get()
            allprocesses = allprocesses - set([diedprocess])
            if retcode != 0:
                [ p.kill() for p in allprocesses ]
                raise subprocess.CalledProcessError(retcode, diedprocess._saved_args)
예제 #7
0
class ZFSConnection:
    host = None
    _poolset = None
    _dirty = True
    _trust = False
    _properties = None
    def __init__(self,host="localhost", trust=False, sshcipher=None, properties=None, identityfile=None, knownhostsfile=None):
        self.host = host
        self._trust = trust
        self._properties = properties if properties else []
        self._poolset= PoolSet()
        if host in ['localhost','127.0.0.1']:
            self.command = ["zfs"]
        else:
            self.command = ["ssh","-o","BatchMode yes","-a","-x"]
            if self._trust:
                self.command.extend(["-o","CheckHostIP no"])
                self.command.extend(["-o","StrictHostKeyChecking no"])
            if sshcipher != None:
                self.command.extend(["-c",sshcipher])
            if identityfile != None:
                self.command.extend(["-i",identityfile])
            if knownhostsfile != None:
                self.command.extend(["-o","UserKnownHostsFile %s" % knownhostsfile])
            self.command.extend([self.host,"zfs"])

    def _get_poolset(self):
        if self._dirty:
            properties = [ 'creation' ] + self._properties
            stdout2 = subprocess.check_output(self.command + ["list", "-Hpr", "-o", ",".join( ['name'] + properties ), "-t", "all"])
            self._poolset.parse_zfs_r_output(stdout2,properties)
            self._dirty = False
        return self._poolset
    pools = property(_get_poolset)

    def create_dataset(self,name):
        subprocess.check_call(self.command + ["create", name])
        self._dirty = True
        return self.pools.lookup(name)

    def destroy_dataset(self, name):
        subprocess.check_call(self.command + ["destroy", name])
        self._dirty = True

    def destroy_recursively(self, name):
        subprocess.check_call(self.command + ["destroy", '-r', name])
        self._dirty = True

    def snapshot_recursively(self,name,snapshotname,properties={}):
        plist = sum( map( lambda x: ['-o', '%s=%s' % x ], properties.items() ), [] )
        subprocess.check_call(self.command + ["snapshot", "-r" ] + plist + [ "%s@%s" % (name, snapshotname)])
        self._dirty = True
    
    def send(self,name,opts=None,bufsize=-1,compression=False):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        cmd = cmd + ["send"] + opts + [name]
        p = SpecialPopen(cmd,stdin=open(os.devnull),stdout=subprocess.PIPE,bufsize=bufsize)
        return p

    def receive(self,name,pipe,opts=None,bufsize=-1,compression=False):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        cmd = cmd + ["receive"] + opts + [name]
        p = SpecialPopen(cmd,stdin=pipe,bufsize=bufsize)
        return p

    def transfer(self, dst_conn, s, d, fromsnapshot=None, showprogress=False, bufsize=-1, send_opts=None, receive_opts=None, ratelimit=-1, compression=False):
        if send_opts is None: send_opts = []
        if receive_opts is None: receive_opts = []
        
        queue_of_killables = Queue()

        if fromsnapshot: fromsnapshot=["-i",fromsnapshot]
        else: fromsnapshot = []
        sndprg = self.send(s, opts=[] + fromsnapshot + send_opts, bufsize=bufsize, compression=compression)
        sndprg_supervisor = Thread(target=lambda: queue_of_killables.put((sndprg, sndprg.wait())))
        sndprg_supervisor.start()

        if showprogress:
            try:
                        barprg = progressbar(pipe=sndprg.stdout,bufsize=bufsize,ratelimit=ratelimit)
                        barprg_supervisor = Thread(target=lambda: queue_of_killables.put((barprg, barprg.wait())))
                        barprg_supervisor.start()
                        sndprg.stdout.close()
            except OSError:
                        os.kill(sndprg.pid,15)
                        raise
        else:
            barprg = sndprg

        try:
                        rcvprg = dst_conn.receive(d,pipe=barprg.stdout,opts=["-Fu"]+receive_opts,bufsize=bufsize,compression=compression)
                        rcvprg_supervisor = Thread(target=lambda: queue_of_killables.put((rcvprg, rcvprg.wait())))
                        rcvprg_supervisor.start()
                        barprg.stdout.close()
        except OSError:
                os.kill(sndprg.pid, 15)
                if sndprg.pid != barprg.pid: os.kill(barprg.pid, 15)
                raise

        dst_conn._dirty = True
        allprocesses = set([rcvprg, sndprg]) | ( set([barprg]) if showprogress else set() )
        while allprocesses:
            diedprocess, retcode = queue_of_killables.get()
            allprocesses = allprocesses - set([diedprocess])
            if retcode != 0:
                [ p.kill() for p in allprocesses ]
                raise subprocess.CalledProcessError(retcode, diedprocess._saved_args)
예제 #8
0
class ZFSConnection:
    host = None
    _poolset = None
    _dirty = True
    _trust = False
    _properties = None
    def __init__(self,host="localhost", trust=False, sshcipher=None, properties=None, identityfile=None, knownhostsfile=None, verbose=False):
        self.host = host
        self._trust = trust
        self._properties = properties if properties else []
        self._poolset= PoolSet()
        self.verbose = verbose
        if host in ['localhost','127.0.0.1']:
            self.command = []
        else:
            self.command = ["ssh","-o","BatchMode=yes","-a","-x"]
            if self._trust:
                self.command.extend(["-o","CheckHostIP=no"])
                self.command.extend(["-o","StrictHostKeyChecking=no"])
            if sshcipher != None:
                self.command.extend(["-c",sshcipher])
            if identityfile != None:
                self.command.extend(["-i",identityfile])
            if knownhostsfile != None:
                self.command.extend(["-o","UserKnownHostsFile=%s" % knownhostsfile])
            self.command.extend([self.host])

    def _get_poolset(self):
        if self._dirty:
            properties = [ 'creation' ] + self._properties
            stdout2 = subprocess.check_output(self.command + ["zfs", "list", "-Hpr", "-o", ",".join( ['name'] + properties ), "-t", "all"])
            self._poolset.parse_zfs_r_output(stdout2,properties)
            self._dirty = False
        return self._poolset
    pools = property(_get_poolset)

    def create_dataset(self, name, parents=False):
        parents_opt = ["-p"] if parents else []
        subprocess.check_call(self.command + ["zfs", "create"] + parents_opt + [name])
        self._dirty = True
        return self.pools.lookup(name)

    def destroy_dataset(self, name):
        subprocess.check_call(self.command + ["zfs", "destroy", name])
        self._dirty = True

    def destroy_recursively(self, name, returnok=False):
        """If returnok, then simply return success as a boolean."""
        ok = True
        cmd = self.command + ["zfs", "destroy", '-r', name]
        if returnok:
            ok = subprocess.call(cmd) == 0
        else:
            subprocess.check_call(cmd)
        self._dirty = True
        return ok

    def snapshot_recursively(self,name,snapshotname,properties={}):
        plist = sum( map( lambda x: ['-o', '%s=%s' % x ], properties.items() ), [] )
        subprocess.check_call(self.command + ["zfs", "snapshot", "-r" ] + plist + [ "%s@%s" % (name, snapshotname)])
        self._dirty = True

    def send(self,name,opts=None,bufsize=-1,compression=False,lockdataset=None):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        if lockdataset is not None:
            cmd += ["zflock"]
            if self.verbose:
                cmd += ["-v"]
            cmd += [lockdataset, "--"]
        cmd += ["zfs", "send"] + opts
        if "-t" not in opts:
            # if we're resuming, don't specify the name of what to send
            cmd += [name]
        verbose_stderr("%s\n" % ' '.join(cmd))
        p = SpecialPopen(cmd,stdin=file(os.devnull),stdout=subprocess.PIPE,bufsize=bufsize)
        return p

    def receive(self,name,pipe,opts=None,bufsize=-1,compression=False,lockdataset=None):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        if lockdataset is not None:
            cmd += ["zflock"]
            if self.verbose:
                cmd += ["-v"]
            cmd += [lockdataset, "--"]
        cmd = cmd + ["zfs", "receive"] + opts + [name]
        verbose_stderr("%s\n" % ' '.join(cmd))
        p = SpecialPopen(cmd,stdin=pipe,bufsize=bufsize)
        return p

    def transfer(self, dst_conn, s, d, fromsnapshot=None, showprogress=False, bufsize=-1, send_opts=None, receive_opts=None, ratelimit=-1, compression=False, locksrcdataset=None, lockdstdataset=None, verbose=False, resumable=False):
        if send_opts is None: send_opts = []
        if receive_opts is None: receive_opts = []

        try:
            resume_token = dst_conn.pools.lookup(d).get_property("receive_resume_token")
        except:
            resume_token = None

        queue_of_killables = Queue()

        if fromsnapshot: fromsnapshot=["-i",fromsnapshot]
        else: fromsnapshot = []
        if verbose: verbose_opts = ["-v"]
        else: verbose_opts = []
        # Regardless of whether resumable is requested this time , if
        # there's a resume token on the destination, we have to use it.
        if resume_token is not None:
            all_send_opts = ["-t", resume_token] + verbose_opts
        else:
            all_send_opts = [] + fromsnapshot + send_opts + verbose_opts
        sndprg = self.send(s, opts=all_send_opts, bufsize=bufsize, compression=compression, lockdataset=locksrcdataset)
        sndprg_supervisor = Thread(target=lambda: queue_of_killables.put((sndprg, sndprg.wait())))
        sndprg_supervisor.start()

        if showprogress:
            try:
                        barprg = progressbar(pipe=sndprg.stdout,bufsize=bufsize,ratelimit=ratelimit)
                        barprg_supervisor = Thread(target=lambda: queue_of_killables.put((barprg, barprg.wait())))
                        barprg_supervisor.start()
                        sndprg.stdout.close()
            except OSError:
                        os.kill(sndprg.pid,15)
                        raise
        else:
            barprg = sndprg

        try:
                        if resumable: resumable_recv_opts = ["-s"]
                        else: resumable_recv_opts = []
                        all_recv_opts = ["-Fu"] + verbose_opts + resumable_recv_opts + receive_opts
                        rcvprg = dst_conn.receive(d,pipe=barprg.stdout,opts=all_recv_opts,bufsize=bufsize,compression=compression, lockdataset=lockdstdataset)
                        rcvprg_supervisor = Thread(target=lambda: queue_of_killables.put((rcvprg, rcvprg.wait())))
                        rcvprg_supervisor.start()
                        barprg.stdout.close()
        except OSError:
                os.kill(sndprg.pid, 15)
                if sndprg.pid != barprg.pid: os.kill(barprg.pid, 15)
                raise

        dst_conn._dirty = True
        allprocesses = set([rcvprg, sndprg]) | ( set([barprg]) if showprogress else set() )
        while allprocesses:
            diedprocess, retcode = queue_of_killables.get()
            allprocesses = allprocesses - set([diedprocess])
            if retcode != 0:
                [ p.kill() for p in allprocesses ]
                raise subprocess.CalledProcessError(retcode, diedprocess._saved_args)
예제 #9
0
class ZFSConnection:
    host = None
    _poolset = None
    _dirty = True
    _trust = False
    def __init__(self,host="localhost", trust=False):
        self.host = host
        self._trust = trust
        self._poolset= PoolSet()
        if host in ['localhost','127.0.0.1']:
            self.command = ["zfs"]
        else:
            self.command = ["ssh","-o","BatchMode yes","-a","-x","-c","arcfour"]
            if self._trust:
                self.command.extend(["-o","CheckHostIP no"])
                self.command.extend(["-o","StrictHostKeyChecking no"])
            self.command.extend([self.host,"zfs"])

    def _get_poolset(self):
        if self._dirty:
            stdout = subprocess.check_output(self.command + ["list", "-r", "-t", "all", "-H", "-o", "name"])
            stdout2 = subprocess.check_output(self.command + ["get", "-r", "-o", "name,value", "creation", "-Hp"])
            self._poolset.parse_zfs_r_output(stdout,stdout2)
            self._dirty = False
        return self._poolset
    pools = property(_get_poolset)

    def create_dataset(self,name):
        subprocess.check_call(self.command + ["create", name])
        self._dirty = True
        return self.pools.lookup(name)

    def destroy_recursively(self, name):
        subprocess.check_call(self.command + ["destroy", '-r', name])
        self._dirty = True

    def snapshot_recursively(self,name,snapshotname):
        subprocess.check_call(self.command + ["snapshot", "-r", "%s@%s" % (name, snapshotname)])
        self._dirty = True

    def send(self,name,opts=None,bufsize=-1,compression=False):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        cmd = cmd + ["send"] + opts + [name]
        p = subprocess.Popen(cmd,stdin=file(os.devnull),stdout=subprocess.PIPE,bufsize=bufsize)
        return p

    def receive(self,name,pipe,opts=None,bufsize=-1,compression=False):
        if not opts: opts = []
        cmd = list(self.command)
        if compression and cmd[0] == 'ssh': cmd.insert(1,"-C")
        cmd = cmd + ["receive"] + opts + [name]
        p = subprocess.Popen(cmd,stdin=pipe,bufsize=bufsize)
        return p

    def transfer(self, dst_conn, s, d, fromsnapshot=None, showprogress=False, bufsize=-1, send_opts=None, receive_opts=None, ratelimit=-1, compression=False):
        if send_opts is None: send_opts = []
        if receive_opts is None: receive_opts = []
        
        if fromsnapshot: fromsnapshot=["-i",fromsnapshot]
        else: fromsnapshot = []
        sndprg = self.send(s, opts=[] + fromsnapshot + send_opts, bufsize=bufsize, compression=compression)
        
        if showprogress:
            try:
                        barprg = progressbar(pipe=sndprg.stdout,bufsize=bufsize,ratelimit=ratelimit)
                        sndprg.stdout.close()
            except OSError:
                        os.kill(sndprg.pid,15)
                        raise
        else:
            barprg = sndprg

        try:
                        rcvprg = dst_conn.receive(d,pipe=barprg.stdout,opts=["-Fu"]+receive_opts,bufsize=bufsize,compression=compression)
                        barprg.stdout.close()
        except OSError:
                os.kill(sndprg.pid, 15)
                if sndprg.pid != barprg.pid: os.kill(barprg.pid, 15)
                raise

        dst_conn._dirty = True
        if showprogress:
            sendret, barret, rcvret = sndprg.wait(), barprg.wait(), rcvprg.wait()
        else:
            sendret, barret, rcvret = sndprg.wait(), 0, rcvprg.wait()
        if sendret:
            raise subprocess.CalledProcessError(sendret, ["zfs", "send"])
        if barret:
            raise subprocess.CalledProcessError(barret, ["clpbar"])
        if rcvret:
            raise subprocess.CalledProcessError(rcvret, ["zfs", "recv"])