コード例 #1
0
ファイル: client.py プロジェクト: david415/tahoe-lafs
    def init_magic_folder(self):
        #print "init_magic_folder"
        if self.get_config("drop_upload", "enabled", False, boolean=True):
            raise OldConfigOptionError("The [drop_upload] section must be renamed to [magic_folder].\n"
                                       "See docs/frontends/magic-folder.rst for more information.")

        if self.get_config("magic_folder", "enabled", False, boolean=True):
            #print "magic folder enabled"
            upload_dircap = self.get_private_config("magic_folder_dircap")
            collective_dircap = self.get_private_config("collective_dircap")

            local_dir_config = self.get_config("magic_folder", "local.directory").decode("utf-8")
            local_dir = abspath_expanduser_unicode(local_dir_config, base=self.basedir)

            dbfile = os.path.join(self.basedir, "private", "magicfolderdb.sqlite")
            dbfile = abspath_expanduser_unicode(dbfile)

            from allmydata.frontends import magic_folder
            umask = self.get_config("magic_folder", "download.umask", 0077)
            s = magic_folder.MagicFolder(self, upload_dircap, collective_dircap, local_dir, dbfile, umask)
            self._magic_folder = s
            s.setServiceParent(self)
            s.startService()

            # start processing the upload queue when we've connected to
            # enough servers
            threshold = min(self.encoding_params["k"],
                            self.encoding_params["happy"] + 1)
            d = self.storage_broker.when_connected_enough(threshold)
            d.addCallback(lambda ign: s.ready())
コード例 #2
0
 def test_web_static(self):
     basedir = u"introducer.Node.test_web_static"
     os.mkdir(basedir)
     fileutil.write(os.path.join(basedir, "tahoe.cfg"),
                    "[node]\n" +
                    "web.port = tcp:0:interface=127.0.0.1\n" +
                    "web.static = relative\n")
     c = IntroducerNode(basedir)
     w = c.getServiceNamed("webish")
     abs_basedir = fileutil.abspath_expanduser_unicode(basedir)
     expected = fileutil.abspath_expanduser_unicode(u"relative", abs_basedir)
     self.failUnlessReallyEqual(w.staticdir, expected)
コード例 #3
0
 def test_manhole_keyfile(self):
     basedir = u"client.Basic.test_manhole_keyfile"
     os.mkdir(basedir)
     fileutil.write(os.path.join(basedir, "tahoe.cfg"),
                    BASECONFIG +
                    "[node]\n" +
                    "ssh.port = tcp:0:interface=127.0.0.1\n" +
                    "ssh.authorized_keys_file = relative\n")
     c = client.Client(basedir)
     m = [s for s in c if isinstance(s, AuthorizedKeysManhole)][0]
     abs_basedir = fileutil.abspath_expanduser_unicode(basedir)
     expected = fileutil.abspath_expanduser_unicode(u"relative", abs_basedir)
     self.failUnlessReallyEqual(m.keyfile, expected)
コード例 #4
0
ファイル: test_client.py プロジェクト: warner/tahoe-lafs
 def test_web_staticdir(self):
     basedir = u"client.Basic.test_web_staticdir"
     os.mkdir(basedir)
     fileutil.write(os.path.join(basedir, "tahoe.cfg"),
                    BASECONFIG +
                    "[node]\n" +
                    "web.port = tcp:0:interface=127.0.0.1\n" +
                    "web.static = relative\n")
     c = client.create_client(basedir)
     w = c.getServiceNamed("webish")
     abs_basedir = fileutil.abspath_expanduser_unicode(basedir)
     expected = fileutil.abspath_expanduser_unicode(u"relative", abs_basedir)
     self.failUnlessReallyEqual(w.staticdir, expected)
コード例 #5
0
    def setup_alice_and_bob(self, alice_clock=reactor, bob_clock=reactor):
        self.set_up_grid(num_clients=2, oneshare=True)

        self.alice_magicfolder = None
        self.bob_magicfolder = None

        alice_magic_dir = abspath_expanduser_unicode(u"Alice-magic", base=self.basedir)
        self.mkdir_nonascii(alice_magic_dir)
        bob_magic_dir = abspath_expanduser_unicode(u"Bob-magic", base=self.basedir)
        self.mkdir_nonascii(bob_magic_dir)

        # Alice creates a Magic Folder,
        # invites herself then and joins.
        d = self.do_create_magic_folder(0)
        d.addCallback(lambda ign: self.do_invite(0, u"Alice\u00F8"))
        def get_invite_code(result):
            self.invite_code = result[1].strip()
        d.addCallback(get_invite_code)
        d.addCallback(lambda ign: self.do_join(0, alice_magic_dir, self.invite_code))
        def get_alice_caps(ign):
            self.alice_collective_dircap, self.alice_upload_dircap = self.get_caps_from_files(0)
        d.addCallback(get_alice_caps)
        d.addCallback(lambda ign: self.check_joined_config(0, self.alice_upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, alice_magic_dir))
        def get_Alice_magicfolder(result):
            self.alice_magicfolder = self.init_magicfolder(0, self.alice_upload_dircap,
                                                           self.alice_collective_dircap,
                                                           alice_magic_dir, alice_clock)
            return result
        d.addCallback(get_Alice_magicfolder)

        # Alice invites Bob. Bob joins.
        d.addCallback(lambda ign: self.do_invite(0, u"Bob\u00F8"))
        def get_invite_code(result):
            self.invite_code = result[1].strip()
        d.addCallback(get_invite_code)
        d.addCallback(lambda ign: self.do_join(1, bob_magic_dir, self.invite_code))
        def get_bob_caps(ign):
            self.bob_collective_dircap, self.bob_upload_dircap = self.get_caps_from_files(1)
        d.addCallback(get_bob_caps)
        d.addCallback(lambda ign: self.check_joined_config(1, self.bob_upload_dircap))
        d.addCallback(lambda ign: self.check_config(1, bob_magic_dir))
        def get_Bob_magicfolder(result):
            self.bob_magicfolder = self.init_magicfolder(1, self.bob_upload_dircap,
                                                         self.bob_collective_dircap,
                                                         bob_magic_dir, bob_clock)
            return result
        d.addCallback(get_Bob_magicfolder)
        return d
コード例 #6
0
ファイル: client.py プロジェクト: warner/tahoe-lafs
    def init_magic_folder(self):
        #print "init_magic_folder"
        if self.get_config("drop_upload", "enabled", False, boolean=True):
            raise OldConfigOptionError("The [drop_upload] section must be renamed to [magic_folder].\n"
                                       "See docs/frontends/magic-folder.rst for more information.")

        if self.get_config("magic_folder", "enabled", False, boolean=True):
            from allmydata.frontends import magic_folder

            try:
                magic_folders = magic_folder.load_magic_folders(self.basedir)
            except Exception as e:
                log.msg("Error loading magic-folder config: {}".format(e))
                raise

            # start processing the upload queue when we've connected to
            # enough servers
            threshold = min(self.encoding_params["k"],
                            self.encoding_params["happy"] + 1)

            for (name, mf_config) in magic_folders.items():
                self.log("Starting magic_folder '{}'".format(name))
                db_filename = os.path.join(self.basedir, "private", "magicfolder_{}.sqlite".format(name))
                local_dir_config = mf_config['directory']
                try:
                    poll_interval = int(mf_config["poll_interval"])
                except ValueError:
                    raise ValueError("'poll_interval' option must be an int")

                s = magic_folder.MagicFolder(
                    client=self,
                    upload_dircap=mf_config["upload_dircap"].encode('ascii'),
                    collective_dircap=mf_config["collective_dircap"].encode('ascii'),
                    local_path_u=abspath_expanduser_unicode(local_dir_config, base=self.basedir),
                    dbfile=abspath_expanduser_unicode(db_filename),
                    umask=self.get_config("magic_folder", "download.umask", 0077),
                    name=name,
                    downloader_delay=poll_interval,
                )
                self._magic_folders[name] = s
                s.setServiceParent(self)
                s.startService()

                connected_d = self.storage_broker.when_connected_enough(threshold)
                def connected_enough(ign, mf):
                    mf.ready()  # returns a Deferred we ignore
                    return None
                connected_d.addCallback(connected_enough, s)
コード例 #7
0
ファイル: node.py プロジェクト: warner/tahoe-lafs
    def __init__(self, config, basedir=u"."):
        """
        Initialize the node with the given configuration. It's base directory
        is the current directory by default.
        """
        service.MultiService.__init__(self)
        # ideally, this would only be in _Config (or otherwise abstracted)
        self.basedir = abspath_expanduser_unicode(unicode(basedir))
        # XXX don't write files in ctor!
        fileutil.make_dirs(os.path.join(self.basedir, "private"), 0700)
        with open(os.path.join(self.basedir, "private", "README"), "w") as f:
            f.write(PRIV_README)

        self.config = config
        self.get_config = config.get_config # XXX stopgap
        self.nickname = config.nickname # XXX stopgap

        self.init_tempdir()
        self.check_privacy()

        self.create_log_tub()
        self.logSource = "Node"
        self.setup_logging()

        self.create_i2p_provider()
        self.create_tor_provider()
        self.init_connections()
        self.set_tub_options()
        self.create_main_tub()
        self.create_control_tub()

        self.log("Node constructed. " + get_package_versions_string())
        iputil.increase_rlimits()
コード例 #8
0
    def test_join_twice_failure(self):
        self.basedir = "cli/MagicFolder/create-join-twice-failure"
        os.makedirs(self.basedir)
        self.set_up_grid(oneshare=True)
        local_dir = os.path.join(self.basedir, "magic")
        abs_local_dir_u = abspath_expanduser_unicode(unicode(local_dir), long_path=False)

        d = self.do_create_magic_folder(0)
        d.addCallback(lambda ign: self.do_invite(0, self.alice_nickname))
        def get_invite_code_and_join((rc, stdout, stderr)):
            self.invite_code = stdout.strip()
            return self.do_join(0, unicode(local_dir), self.invite_code)
        d.addCallback(get_invite_code_and_join)
        def get_caps(ign):
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(0)
        d.addCallback(get_caps)
        d.addCallback(lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))
        def join_again(ignore):
            return self.do_cli("magic-folder", "join", self.invite_code, local_dir, client_num=0)
        d.addCallback(join_again)
        def get_results(result):
            (rc, out, err) = result
            self.failUnlessEqual(out, "")
            self.failUnlessIn("This client has already joined a magic folder.", err)
            self.failUnlessIn("Use the 'tahoe magic-folder leave' command first.", err)
            self.failIfEqual(rc, 0)
        d.addCallback(get_results)
        return d
コード例 #9
0
ファイル: test_put.py プロジェクト: LeastAuthority/tahoe-lafs
    def test_unlinked_immutable_from_file(self):
        # tahoe put file.txt
        # tahoe put ./file.txt
        # tahoe put /tmp/file.txt
        # tahoe put ~/file.txt
        self.basedir = "cli/Put/unlinked_immutable_from_file"
        self.set_up_grid(oneshare=True)

        rel_fn = os.path.join(self.basedir, "DATAFILE")
        abs_fn = unicode_to_argv(abspath_expanduser_unicode(unicode(rel_fn)))
        # we make the file small enough to fit in a LIT file, for speed
        fileutil.write(rel_fn, "short file")
        d = self.do_cli("put", rel_fn)
        def _uploaded((rc, out, err)):
            readcap = out
            self.failUnless(readcap.startswith("URI:LIT:"), readcap)
            self.readcap = readcap
        d.addCallback(_uploaded)
        d.addCallback(lambda res: self.do_cli("put", "./" + rel_fn))
        d.addCallback(lambda (rc,stdout,stderr):
                      self.failUnlessReallyEqual(stdout, self.readcap))
        d.addCallback(lambda res: self.do_cli("put", abs_fn))
        d.addCallback(lambda (rc,stdout,stderr):
                      self.failUnlessReallyEqual(stdout, self.readcap))
        # we just have to assume that ~ is handled properly
        return d
コード例 #10
0
ファイル: test_client.py プロジェクト: WinLAFS/tahoe-lafs
    def test_error_on_old_config_files(self, mock_log_msg):
        basedir = "test_client.Basic.test_error_on_old_config_files"
        os.mkdir(basedir)
        fileutil.write(os.path.join(basedir, "tahoe.cfg"),
                       BASECONFIG +
                       "[storage]\n" +
                       "enabled = false\n" +
                       "reserved_space = bogus\n")
        fileutil.write(os.path.join(basedir, "introducer.furl"), "")
        fileutil.write(os.path.join(basedir, "no_storage"), "")
        fileutil.write(os.path.join(basedir, "readonly_storage"), "")
        fileutil.write(os.path.join(basedir, "debug_discard_storage"), "")

        e = self.failUnlessRaises(OldConfigError, client.Client, basedir)
        abs_basedir = fileutil.abspath_expanduser_unicode(unicode(basedir)).encode(sys.getfilesystemencoding())
        self.failUnlessIn(os.path.join(abs_basedir, "introducer.furl"), e.args[0])
        self.failUnlessIn(os.path.join(abs_basedir, "no_storage"), e.args[0])
        self.failUnlessIn(os.path.join(abs_basedir, "readonly_storage"), e.args[0])
        self.failUnlessIn(os.path.join(abs_basedir, "debug_discard_storage"), e.args[0])

        for oldfile in ['introducer.furl', 'no_storage', 'readonly_storage',
                        'debug_discard_storage']:
            logged = [ m for m in mock_log_msg.call_args_list if
                       ("Found pre-Tahoe-LAFS-v1.3 configuration file" in str(m[0][0]) and oldfile in str(m[0][0])) ]
            self.failUnless(logged, (oldfile, mock_log_msg.call_args_list))

        for oldfile in [
            'nickname', 'webport', 'keepalive_timeout', 'log_gatherer.furl',
            'disconnect_timeout', 'advertised_ip_addresses', 'helper.furl',
            'key_generator.furl', 'stats_gatherer.furl', 'sizelimit',
            'run_helper']:
            logged = [ m for m in mock_log_msg.call_args_list if
                       ("Found pre-Tahoe-LAFS-v1.3 configuration file" in str(m[0][0]) and oldfile in str(m[0][0])) ]
            self.failIf(logged, oldfile)
コード例 #11
0
    def test_join_leave_join(self):
        self.basedir = "cli/MagicFolder/create-join-leave-join"
        os.makedirs(self.basedir)
        self.set_up_grid(oneshare=True)
        local_dir = os.path.join(self.basedir, "magic")
        abs_local_dir_u = abspath_expanduser_unicode(unicode(local_dir), long_path=False)

        self.invite_code = None
        d = self.do_create_magic_folder(0)
        d.addCallback(lambda ign: self.do_invite(0, self.alice_nickname))
        def get_invite_code_and_join((rc, stdout, stderr)):
            self.failUnlessEqual(rc, 0)
            self.invite_code = stdout.strip()
            return self.do_join(0, unicode(local_dir), self.invite_code)
        d.addCallback(get_invite_code_and_join)
        def get_caps(ign):
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(0)
        d.addCallback(get_caps)
        d.addCallback(lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))
        d.addCallback(lambda ign: self.do_leave(0))

        d.addCallback(lambda ign: self.do_join(0, unicode(local_dir), self.invite_code))
        def get_caps(ign):
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(0)
        d.addCallback(get_caps)
        d.addCallback(lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))

        return d
コード例 #12
0
ファイル: test_node.py プロジェクト: tahoe-lafs/tahoe-lafs
    def test_private_config(self):
        basedir = u"test_node/test_private_config"
        privdir = os.path.join(basedir, "private")
        fileutil.make_dirs(privdir)
        f = open(os.path.join(privdir, 'already'), 'wt')
        f.write("secret")
        f.close()

        basedir = fileutil.abspath_expanduser_unicode(basedir)
        config = config_from_string(basedir, "", "")

        self.assertEqual(config.get_private_config("already"), "secret")
        self.assertEqual(config.get_private_config("not", "default"), "default")
        self.assertRaises(MissingConfigEntry, config.get_private_config, "not")
        value = config.get_or_create_private_config("new", "start")
        self.assertEqual(value, "start")
        self.assertEqual(config.get_private_config("new"), "start")
        counter = []
        def make_newer():
            counter.append("called")
            return "newer"
        value = config.get_or_create_private_config("newer", make_newer)
        self.assertEqual(len(counter), 1)
        self.assertEqual(value, "newer")
        self.assertEqual(config.get_private_config("newer"), "newer")

        value = config.get_or_create_private_config("newer", make_newer)
        self.assertEqual(len(counter), 1) # don't call unless necessary
        self.assertEqual(value, "newer")
コード例 #13
0
ファイル: tahoe_backup.py プロジェクト: p-static/tahoe-lafs
    def run(self):
        options = self.options
        nodeurl = options['node-url']
        self.verbosity = 1
        if options['quiet']:
            self.verbosity = 0
        if options['verbose']:
            self.verbosity = 2
        stdout = options.stdout
        stderr = options.stderr

        start_timestamp = datetime.datetime.now()
        self.backupdb = None
        bdbfile = os.path.join(options["node-directory"],
                               "private", "backupdb.sqlite")
        bdbfile = abspath_expanduser_unicode(bdbfile)
        self.backupdb = backupdb.get_backupdb(bdbfile, stderr)
        if not self.backupdb:
            print >>stderr, "ERROR: Unable to load backup db."
            return 1

        try:
            rootcap, path = get_alias(options.aliases, options.to_dir, DEFAULT_ALIAS)
        except UnknownAliasError, e:
            e.display(stderr)
            return 1
コード例 #14
0
ファイル: node.py プロジェクト: LeastAuthority/tahoe-lafs
    def __init__(self, basedir=u"."):
        service.MultiService.__init__(self)
        self.basedir = abspath_expanduser_unicode(unicode(basedir))
        self.config_fname = os.path.join(self.basedir, "tahoe.cfg")
        self._portnumfile = os.path.join(self.basedir, self.PORTNUMFILE)
        fileutil.make_dirs(os.path.join(self.basedir, "private"), 0700)
        with open(os.path.join(self.basedir, "private", "README"), "w") as f:
            f.write(PRIV_README)

        # creates self.config
        self.read_config()
        nickname_utf8 = self.get_config("node", "nickname", "<unspecified>")
        self.nickname = nickname_utf8.decode("utf-8")
        assert type(self.nickname) is unicode

        self.init_tempdir()
        self.check_privacy()

        self.create_log_tub()
        self.logSource="Node"
        self.setup_logging()

        self.create_i2p_provider()
        self.create_tor_provider()
        self.init_connections()
        self.set_tub_options()
        self.create_main_tub()
        self.create_control_tub()

        self.log("Node constructed. " + get_package_versions_string())
        iputil.increase_rlimits()
コード例 #15
0
ファイル: check_memory.py プロジェクト: GunioRobot/tahoe-lafs
 def __init__(self, basedir, mode):
     self.basedir = basedir = abspath_expanduser_unicode(unicode(basedir))
     if not (basedir + os.path.sep).startswith(abspath_expanduser_unicode(u".") + os.path.sep):
         raise AssertionError("safety issue: basedir must be a subdir")
     self.testdir = testdir = os.path.join(basedir, "test")
     if os.path.exists(testdir):
         shutil.rmtree(testdir)
     fileutil.make_dirs(testdir)
     self.sparent = service.MultiService()
     self.sparent.startService()
     self.proc = None
     self.tub = Tub()
     self.tub.setOption("expose-remote-exception-types", False)
     self.tub.setServiceParent(self.sparent)
     self.mode = mode
     self.failed = False
     self.keepalive_file = None
コード例 #16
0
ファイル: tahoe_cp.py プロジェクト: tahoe-lafs/tahoe-lafs
    def get_source_info(self, source_spec):
        """
        This turns an argv string into a (Local|Tahoe)(File|Directory)Source.
        """
        precondition(isinstance(source_spec, unicode), source_spec)
        rootcap, path_utf8 = get_alias(self.aliases, source_spec, None)
        path = path_utf8.decode("utf-8")
        # any trailing slash is removed in abspath_expanduser_unicode(), so
        # make a note of it here, to throw an error later
        had_trailing_slash = path.endswith("/")
        if rootcap == DefaultAliasMarker:
            # no alias, so this is a local file
            pathname = abspath_expanduser_unicode(path)
            name = os.path.basename(pathname)
            if not os.path.exists(pathname):
                raise MissingSourceError(source_spec, quotefn=quote_local_unicode_path)
            if os.path.isdir(pathname):
                t = LocalDirectorySource(self.progress, pathname, name)
            else:
                if had_trailing_slash:
                    raise FilenameWithTrailingSlashError(source_spec,
                                                         quotefn=quote_local_unicode_path)
                if not os.path.isfile(pathname):
                    raise WeirdSourceError(pathname)
                t = LocalFileSource(pathname, name) # non-empty
        else:
            # this is a tahoe object
            url = self.nodeurl + "uri/%s" % urllib.quote(rootcap)
            name = None
            if path:
                if path.endswith("/"):
                    path = path[:-1]
                url += "/" + escape_path(path)
                last_slash = path.rfind(u"/")
                name = path
                if last_slash != -1:
                    name = path[last_slash+1:]

            resp = do_http("GET", url + "?t=json")
            if resp.status == 404:
                raise MissingSourceError(source_spec)
            elif resp.status != 200:
                raise HTTPError("Error examining source %s" % quote_output(source_spec),
                                resp)
            parsed = json.loads(resp.read())
            nodetype, d = parsed
            if nodetype == "dirnode":
                t = TahoeDirectorySource(self.nodeurl, self.cache,
                                         self.progress, name)
                t.init_from_parsed(parsed)
            else:
                if had_trailing_slash:
                    raise FilenameWithTrailingSlashError(source_spec)
                writecap = to_str(d.get("rw_uri"))
                readcap = to_str(d.get("ro_uri"))
                mutable = d.get("mutable", False) # older nodes don't provide it
                t = TahoeFileSource(self.nodeurl, mutable, writecap, readcap, name)
        return t
コード例 #17
0
ファイル: node.py プロジェクト: FiloSottile/tahoe-lafs
 def setup_ssh(self):
     ssh_port = self.get_config("node", "ssh.port", "")
     if ssh_port:
         ssh_keyfile_config = self.get_config("node", "ssh.authorized_keys_file").decode('utf-8')
         ssh_keyfile = abspath_expanduser_unicode(ssh_keyfile_config, base=self.basedir)
         from allmydata import manhole
         m = manhole.AuthorizedKeysManhole(ssh_port, ssh_keyfile)
         m.setServiceParent(self)
         self.log("AuthorizedKeysManhole listening on %s" % (ssh_port,))
コード例 #18
0
ファイル: server.py プロジェクト: gvsurenderreddy/tahoe-lafs
    def init_web(self, webport):
        self.log("init_web(webport=%s)", args=(webport,), umid="2bUygA")

        from allmydata.webish import IntroducerWebishServer
        nodeurl_path = os.path.join(self.basedir, u"node.url")
        config_staticdir = self.get_config("node", "web.static", "public_html").decode('utf-8')
        staticdir = abspath_expanduser_unicode(config_staticdir, base=self.basedir)
        ws = IntroducerWebishServer(self, webport, nodeurl_path, staticdir)
        self.add_service(ws)
コード例 #19
0
ファイル: client.py プロジェクト: david415/tahoe-lafs
    def init_web(self, webport):
        self.log("init_web(webport=%s)", args=(webport,))

        from allmydata.webish import WebishServer
        nodeurl_path = os.path.join(self.basedir, "node.url")
        staticdir_config = self.get_config("node", "web.static", "public_html").decode("utf-8")
        staticdir = abspath_expanduser_unicode(staticdir_config, base=self.basedir)
        ws = WebishServer(self, webport, nodeurl_path, staticdir)
        self.add_service(ws)
コード例 #20
0
    def init_magicfolder(self, client_num, upload_dircap, collective_dircap, local_magic_dir, clock):
        dbfile = abspath_expanduser_unicode(u"magicfolderdb.sqlite", base=self.get_clientdir(i=client_num))
        magicfolder = MagicFolder(self.get_client(client_num), upload_dircap, collective_dircap, local_magic_dir,
                                       dbfile, 0077, pending_delay=0.2, clock=clock)
        magicfolder.downloader._turn_delay = 0

        magicfolder.setServiceParent(self.get_client(client_num))
        magicfolder.ready()
        return magicfolder
コード例 #21
0
ファイル: inotify.py プロジェクト: tahoe-lafs/tahoe-lafs
    def process(self, event):
        event_filepath_u = event.src_path.decode(encodingutil.get_filesystem_encoding())
        event_filepath_u = abspath_expanduser_unicode(event_filepath_u, base=self._path)

        if event_filepath_u == self._path:
            # ignore events for parent directory
            return

        self._maybe_notify(event_filepath_u, event)
コード例 #22
0
def argv_to_abspath(s, **kwargs):
    """
    Convenience function to decode an argv element to an absolute path, with ~ expanded.
    If this fails, raise a UsageError.
    """
    decoded = argv_to_unicode(s)
    if decoded.startswith(u'-'):
        raise usage.UsageError("Path argument %s cannot start with '-'.\nUse %s if you intended to refer to a file."
                               % (quote_output(s), quote_output(os.path.join('.', s))))
    return abspath_expanduser_unicode(decoded, **kwargs)
コード例 #23
0
ファイル: tahoe_cp.py プロジェクト: WinLAFS/tahoe-lafs
    def get_source_info(self, source_spec):
        """
        This turns an argv string into a (Local|Tahoe)(File|Directory)Source.
        """
        precondition(isinstance(source_spec, unicode), source_spec)
        rootcap, path_utf8 = get_alias(self.aliases, source_spec, None)
        path = path_utf8.decode("utf-8")
        if rootcap == DefaultAliasMarker:
            # no alias, so this is a local file
            pathname = abspath_expanduser_unicode(path)
            name = os.path.basename(pathname)
            if not os.path.exists(pathname):
                raise MissingSourceError(source_spec, quotefn=quote_local_unicode_path)
            if os.path.isdir(pathname):
                t = LocalDirectorySource(self.progress, pathname, name)
            else:
                assert os.path.isfile(pathname)
                t = LocalFileSource(pathname, name) # non-empty
        else:
            # this is a tahoe object
            url = self.nodeurl + "uri/%s" % urllib.quote(rootcap)
            name = None
            if path:
                url += "/" + escape_path(path)
                last_slash = path.rfind(u"/")
                name = path
                if last_slash != -1:
                    name = path[last_slash+1:]

            resp = do_http("GET", url + "?t=json")
            if resp.status == 404:
                raise MissingSourceError(source_spec)
            elif resp.status != 200:
                raise HTTPError("Error examining source %s" % quote_output(source_spec),
                                resp)
            parsed = simplejson.loads(resp.read())
            nodetype, d = parsed
            if nodetype == "dirnode":
                t = TahoeDirectorySource(self.nodeurl, self.cache,
                                         self.progress, name)
                t.init_from_parsed(parsed)
            else:
                writecap = to_str(d.get("rw_uri"))
                readcap = to_str(d.get("ro_uri"))
                mutable = d.get("mutable", False) # older nodes don't provide it

                last_slash = source_spec.rfind(u"/")
                if last_slash != -1:
                    # TODO: this looks funny and redundant with the 'name'
                    # assignment above. cf #2329
                    name = source_spec[last_slash+1:]

                t = TahoeFileSource(self.nodeurl, mutable, writecap, readcap, name)
        return t
コード例 #24
0
ファイル: node.py プロジェクト: tahoe-lafs/tahoe-lafs
 def get_config_path(self, *args):
     """
     returns an absolute path inside the config directory with any
     extra args join()-ed
     """
     # note: we re-expand here (_basedir already went through this
     # expanduser function) in case the path we're being asked for
     # has embedded ".."'s in it
     return abspath_expanduser_unicode(
         os.path.join(self._basedir, *args)
     )
コード例 #25
0
ファイル: node.py プロジェクト: ozbloke/tahoe-lafs
 def init_tempdir(self):
     tempdir_config = self.get_config("node", "tempdir", "tmp").decode('utf-8')
     tempdir = abspath_expanduser_unicode(tempdir_config, base=self.basedir)
     if not os.path.exists(tempdir):
         fileutil.make_dirs(tempdir)
     tempfile.tempdir = tempdir
     # this should cause twisted.web.http (which uses
     # tempfile.TemporaryFile) to put large request bodies in the given
     # directory. Without this, the default temp dir is usually /tmp/,
     # which is frequently too small.
     test_name = tempfile.mktemp()
     _assert(os.path.dirname(test_name) == tempdir, test_name, tempdir)
コード例 #26
0
    def setUp(self):
        yield super(StatusMagicFolder, self).setUp()
        self.basedir="mf_list"
        self.set_up_grid(oneshare=True)
        self.local_dir = os.path.join(self.basedir, "magic")
        os.mkdir(self.local_dir)
        self.abs_local_dir_u = abspath_expanduser_unicode(unicode(self.local_dir), long_path=False)

        yield self.do_create_magic_folder(0)
        (rc, stdout, stderr) = yield self.do_invite(0, self.alice_nickname)
        invite_code = stdout.strip()
        yield self.do_join(0, unicode(self.local_dir), invite_code)
コード例 #27
0
ファイル: client.py プロジェクト: pombredanne/tahoe-lafs
    def init_ftp_server(self):
        if self.get_config("ftpd", "enabled", False, boolean=True):
            accountfile = from_utf8_or_none(self.get_config("ftpd", "accounts.file", None))
            if accountfile:
                accountfile = abspath_expanduser_unicode(accountfile, base=self.basedir)
            accounturl = self.get_config("ftpd", "accounts.url", None)
            ftp_portstr = self.get_config("ftpd", "port", "8021")

            from allmydata.frontends import ftpd

            s = ftpd.FTPServer(self, accountfile, accounturl, ftp_portstr)
            s.setServiceParent(self)
コード例 #28
0
ファイル: test_cli_backup.py プロジェクト: WinLAFS/tahoe-lafs
    def test_exclude_from_tilde_expansion(self, mock):
        basedir = "cli/Backup/exclude_from_tilde_expansion"
        fileutil.make_dirs(basedir)
        nodeurl_path = os.path.join(basedir, 'node.url')
        fileutil.write(nodeurl_path, 'http://example.net:2357/')
        def parse(args): return parse_options(basedir, "backup", args)

        # ensure that tilde expansion is performed on exclude-from argument
        exclude_file = u'~/.tahoe/excludes.dummy'

        mock.return_value = StringIO()
        parse(['--exclude-from', unicode_to_argv(exclude_file), 'from', 'to'])
        self.failUnlessIn(((abspath_expanduser_unicode(exclude_file),), {}), mock.call_args_list)
コード例 #29
0
    def test_create_invite_join(self):
        self.basedir = "cli/MagicFolder/create-invite-join"
        self.set_up_grid(oneshare=True)
        local_dir = os.path.join(self.basedir, "magic")
        abs_local_dir_u = abspath_expanduser_unicode(unicode(local_dir), long_path=False)

        d = self.do_cli("magic-folder", "create", "magic:", "Alice", local_dir)
        def _done((rc, stdout, stderr)):
            self.failUnlessEqual(rc, 0)
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(0)
        d.addCallback(_done)
        d.addCallback(lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))
        return d
コード例 #30
0
ファイル: client.py プロジェクト: pombredanne/tahoe-lafs
    def init_sftp_server(self):
        if self.get_config("sftpd", "enabled", False, boolean=True):
            accountfile = from_utf8_or_none(self.get_config("sftpd", "accounts.file", None))
            if accountfile:
                accountfile = abspath_expanduser_unicode(accountfile, base=self.basedir)
            accounturl = self.get_config("sftpd", "accounts.url", None)
            sftp_portstr = self.get_config("sftpd", "port", "8022")
            pubkey_file = from_utf8_or_none(self.get_config("sftpd", "host_pubkey_file"))
            privkey_file = from_utf8_or_none(self.get_config("sftpd", "host_privkey_file"))

            from allmydata.frontends import sftpd

            s = sftpd.SFTPServer(self, accountfile, accounturl, sftp_portstr, pubkey_file, privkey_file)
            s.setServiceParent(self)
コード例 #31
0
    def get_source_info(self, source_spec):
        rootcap, path = get_alias(self.aliases, source_spec, None)
        if rootcap == DefaultAliasMarker:
            # no alias, so this is a local file
            pathname = abspath_expanduser_unicode(path.decode('utf-8'))
            name = os.path.basename(pathname)
            if not os.path.exists(pathname):
                raise MissingSourceError(source_spec)
            if os.path.isdir(pathname):
                t = LocalDirectorySource(self.progress, pathname)
            else:
                assert os.path.isfile(pathname)
                t = LocalFileSource(pathname) # non-empty
        else:
            # this is a tahoe object
            url = self.nodeurl + "uri/%s" % urllib.quote(rootcap)
            name = None
            if path:
                url += "/" + escape_path(path)
                last_slash = path.rfind("/")
                name = path
                if last_slash:
                    name = path[last_slash+1:]

            resp = do_http("GET", url + "?t=json")
            if resp.status == 404:
                raise MissingSourceError(source_spec)
            elif resp.status != 200:
                raise HTTPError("Error examining source %s" % quote_output(source_spec),
                                resp)
            parsed = simplejson.loads(resp.read())
            nodetype, d = parsed
            if nodetype == "dirnode":
                t = TahoeDirectorySource(self.nodeurl, self.cache,
                                         self.progress)
                t.init_from_parsed(parsed)
            else:
                writecap = to_str(d.get("rw_uri"))
                readcap = to_str(d.get("ro_uri"))
                mutable = d.get("mutable", False) # older nodes don't provide it
                if source_spec.rfind('/') != -1:
                    name = source_spec[source_spec.rfind('/')+1:]
                t = TahoeFileSource(self.nodeurl, mutable, writecap, readcap)
        return name, t
コード例 #32
0
def read_config(basedir, portnumfile, generated_files=[], _valid_config=None):
    """
    Read and validate configuration.

    :param unicode basedir: directory where configuration data begins

    :param unicode portnumfile: filename fragment for "port number" files

    :param list generated_files: a list of automatically-generated
        configuration files.

    :param ValidConfiguration _valid_config: (internal use, optional) a
        structure defining valid configuration sections and keys

    :returns: :class:`allmydata.node._Config` instance
    """
    basedir = abspath_expanduser_unicode(ensure_text(basedir))
    if _valid_config is None:
        _valid_config = _common_valid_config()

    # complain if there's bad stuff in the config dir
    _error_about_old_config_files(basedir, generated_files)

    # canonicalize the portnum file
    portnumfile = os.path.join(basedir, portnumfile)

    config_path = FilePath(basedir).child("tahoe.cfg")
    try:
        config_str = config_path.getContent()
    except EnvironmentError as e:
        if e.errno != errno.ENOENT:
            raise
        # The file is missing, just create empty ConfigParser.
        config_str = u""
    else:
        config_str = config_str.decode("utf-8-sig")

    return config_from_string(
        basedir,
        portnumfile,
        config_str,
        _valid_config,
        config_path,
    )
コード例 #33
0
ファイル: tahoe_cp.py プロジェクト: tahoe-lafs/tahoe-lafs
    def get_target_info(self, destination_spec):
        precondition(isinstance(destination_spec, str), destination_spec)
        rootcap, path_utf8 = get_alias(self.aliases, destination_spec, None)
        path = path_utf8.decode("utf-8")
        if rootcap == DefaultAliasMarker:
            # no alias, so this is a local file
            pathname = abspath_expanduser_unicode(path)
            if not os.path.exists(pathname):
                t = LocalMissingTarget(pathname)
            elif os.path.isdir(pathname):
                t = LocalDirectoryTarget(self.progress, pathname)
            else:
                # TODO: should this be _assert? what happens if the target is
                # a special file?
                assert os.path.isfile(pathname), pathname
                t = LocalFileTarget(pathname)  # non-empty
        else:
            # this is a tahoe object
            url = self.nodeurl + "uri/%s" % url_quote(rootcap)
            if path:
                url += "/" + escape_path(path)

            resp = do_http("GET", url + "?t=json")
            if resp.status == 404:
                # doesn't exist yet
                t = TahoeMissingTarget(url)
            elif resp.status == 200:
                parsed = json.loads(resp.read())
                nodetype, d = parsed
                if nodetype == "dirnode":
                    t = TahoeDirectoryTarget(self.nodeurl, self.cache,
                                             self.progress)
                    t.init_from_parsed(parsed)
                else:
                    writecap = to_bytes(d.get("rw_uri"))
                    readcap = to_bytes(d.get("ro_uri"))
                    mutable = d.get("mutable", False)
                    t = TahoeFileTarget(self.nodeurl, mutable, writecap,
                                        readcap, url)
            else:
                raise HTTPError(
                    "Error examining target %s" %
                    quote_output(destination_spec), resp)
        return t
コード例 #34
0
    def test_join_twice_failure(self):
        self.basedir = "cli/MagicFolder/create-join-twice-failure"
        os.makedirs(self.basedir)
        self.set_up_grid(oneshare=True)
        local_dir = os.path.join(self.basedir, "magic")
        abs_local_dir_u = abspath_expanduser_unicode(unicode(local_dir),
                                                     long_path=False)

        d = self.do_create_magic_folder(0)
        d.addCallback(lambda ign: self.do_invite(0, self.alice_nickname))

        def get_invite_code_and_join(args):
            (rc, stdout, stderr) = args
            self.invite_code = stdout.strip()
            return self.do_join(0, unicode(local_dir), self.invite_code)

        d.addCallback(get_invite_code_and_join)

        def get_caps(ign):
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(
                0)

        d.addCallback(get_caps)
        d.addCallback(
            lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))

        def join_again(ignore):
            return self.do_cli("magic-folder",
                               "join",
                               self.invite_code,
                               local_dir,
                               client_num=0)

        d.addCallback(join_again)

        def get_results(result):
            (rc, out, err) = result
            self.failUnlessEqual(out, "")
            self.failUnlessIn("This client already has a magic-folder", err)
            self.failIfEqual(rc, 0)

        d.addCallback(get_results)
        return d
コード例 #35
0
    def test_error_on_old_config_files(self):
        basedir = "test_client.Basic.test_error_on_old_config_files"
        os.mkdir(basedir)
        fileutil.write(os.path.join(basedir, "tahoe.cfg"),
                       BASECONFIG +
                       "[storage]\n" +
                       "enabled = false\n" +
                       "reserved_space = bogus\n")
        fileutil.write(os.path.join(basedir, "introducer.furl"), "")
        fileutil.write(os.path.join(basedir, "no_storage"), "")
        fileutil.write(os.path.join(basedir, "readonly_storage"), "")
        fileutil.write(os.path.join(basedir, "debug_discard_storage"), "")

        logged_messages = []
        self.patch(twisted.python.log, 'msg', logged_messages.append)

        e = self.failUnlessRaises(
            OldConfigError,
            read_config,
            basedir,
            "client.port",
            _valid_config_sections=client._valid_config_sections,
        )
        abs_basedir = fileutil.abspath_expanduser_unicode(unicode(basedir)).encode(sys.getfilesystemencoding())
        self.failUnlessIn(os.path.join(abs_basedir, "introducer.furl"), e.args[0])
        self.failUnlessIn(os.path.join(abs_basedir, "no_storage"), e.args[0])
        self.failUnlessIn(os.path.join(abs_basedir, "readonly_storage"), e.args[0])
        self.failUnlessIn(os.path.join(abs_basedir, "debug_discard_storage"), e.args[0])

        for oldfile in ['introducer.furl', 'no_storage', 'readonly_storage',
                        'debug_discard_storage']:
            logged = [ m for m in logged_messages if
                       ("Found pre-Tahoe-LAFS-v1.3 configuration file" in str(m) and oldfile in str(m)) ]
            self.failUnless(logged, (oldfile, logged_messages))

        for oldfile in [
            'nickname', 'webport', 'keepalive_timeout', 'log_gatherer.furl',
            'disconnect_timeout', 'advertised_ip_addresses', 'helper.furl',
            'key_generator.furl', 'stats_gatherer.furl', 'sizelimit',
            'run_helper']:
            logged = [ m for m in logged_messages if
                       ("Found pre-Tahoe-LAFS-v1.3 configuration file" in str(m) and oldfile in str(m)) ]
            self.failIf(logged, (oldfile, logged_messages))
コード例 #36
0
    def test_join_leave_join(self):
        self.basedir = "cli/MagicFolder/create-join-leave-join"
        os.makedirs(self.basedir)
        self.set_up_grid(oneshare=True)
        local_dir = os.path.join(self.basedir, "magic")
        abs_local_dir_u = abspath_expanduser_unicode(unicode(local_dir),
                                                     long_path=False)

        self.invite_code = None
        d = self.do_create_magic_folder(0)
        d.addCallback(lambda ign: self.do_invite(0, self.alice_nickname))

        def get_invite_code_and_join(args):
            (rc, stdout, stderr) = args
            self.failUnlessEqual(rc, 0)
            self.invite_code = stdout.strip()
            return self.do_join(0, unicode(local_dir), self.invite_code)

        d.addCallback(get_invite_code_and_join)

        def get_caps(ign):
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(
                0)

        d.addCallback(get_caps)
        d.addCallback(
            lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))
        d.addCallback(lambda ign: self.do_leave(0))

        d.addCallback(
            lambda ign: self.do_join(0, unicode(local_dir), self.invite_code))

        def get_caps(ign):
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(
                0)

        d.addCallback(get_caps)
        d.addCallback(
            lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))

        return d
コード例 #37
0
    def test_create_invite_join(self):
        self.basedir = "cli/MagicFolder/create-invite-join"
        self.set_up_grid(oneshare=True)
        local_dir = os.path.join(self.basedir, "magic")
        abs_local_dir_u = abspath_expanduser_unicode(unicode(local_dir),
                                                     long_path=False)

        d = self.do_cli("magic-folder", "create", "magic:", "Alice", local_dir)

        def _done((rc, stdout, stderr)):
            self.failUnlessEqual(rc, 0)
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(
                0)

        d.addCallback(_done)
        d.addCallback(
            lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))
        return d
コード例 #38
0
ファイル: auth.py プロジェクト: raystyle/CloudMalwareAlarm
 def __init__(self, client, accountfile):
     self.client = client
     self.passwords = {}
     self.pubkeys = {}
     self.rootcaps = {}
     for line in open(abspath_expanduser_unicode(accountfile), "r"):
         line = line.strip()
         if line.startswith("#") or not line:
             continue
         name, passwd, rest = line.split(None, 2)
         if passwd.startswith("ssh-"):
             bits = rest.split()
             keystring = " ".join([passwd] + bits[:-1])
             rootcap = bits[-1]
             self.pubkeys[name] = keystring
         else:
             self.passwords[name] = passwd
             rootcap = rest
         self.rootcaps[name] = rootcap
コード例 #39
0
    def init_magicfolder(self, client_num, upload_dircap, collective_dircap,
                         local_magic_dir, clock):
        dbfile = abspath_expanduser_unicode(
            u"magicfolderdb.sqlite", base=self.get_clientdir(i=client_num))
        magicfolder = MagicFolder(
            client=self.get_client(client_num),
            upload_dircap=upload_dircap,
            collective_dircap=collective_dircap,
            local_path_u=local_magic_dir,
            dbfile=dbfile,
            umask=0o077,
            pending_delay=0.2,
            clock=clock,
        )
        magicfolder.downloader._turn_delay = 0

        magicfolder.setServiceParent(self.get_client(client_num))
        magicfolder.ready()
        return magicfolder
コード例 #40
0
    def __init__(self, configparser, portnum_fname, basedir, config_fname):
        """
        :param configparser: a ConfigParser instance

        :param portnum_fname: filename to use for the port-number file
           (a relative path inside basedir)

        :param basedir: path to our "node directory", inside which all
           configuration is managed

        :param config_fname: the pathname actually used to create the
            configparser (might be 'fake' if using in-memory data)
        """
        self.portnum_fname = portnum_fname
        self._basedir = abspath_expanduser_unicode(ensure_text(basedir))
        self._config_fname = config_fname
        self.config = configparser
        self.nickname = self.get_config("node", "nickname", u"<unspecified>")
        assert isinstance(self.nickname, str)
コード例 #41
0
def read_config(basedir, portnumfile, generated_files=[], _valid_config=None):
    """
    Read and validate configuration.

    :param unicode basedir: directory where configuration data begins

    :param unicode portnumfile: filename fragment for "port number" files

    :param list generated_files: a list of automatically-generated
        configuration files.

    :param ValidConfiguration _valid_config: (internal use, optional) a
        structure defining valid configuration sections and keys

    :returns: :class:`allmydata.node._Config` instance
    """
    basedir = abspath_expanduser_unicode(ensure_text(basedir))
    if _valid_config is None:
        _valid_config = _common_valid_config()

    # complain if there's bad stuff in the config dir
    _error_about_old_config_files(basedir, generated_files)

    # canonicalize the portnum file
    portnumfile = os.path.join(basedir, portnumfile)

    # (try to) read the main config file
    config_fname = os.path.join(basedir, "tahoe.cfg")
    try:
        parser = configutil.get_config(config_fname)
    except EnvironmentError as e:
        if e.errno != errno.ENOENT:
            raise
        # The file is missing, just create empty ConfigParser.
        parser = configutil.get_config_from_string(u"")

    configutil.validate_config(config_fname, parser, _valid_config)

    # make sure we have a private configuration area
    fileutil.make_dirs(os.path.join(basedir, "private"), 0o700)

    return _Config(parser, portnumfile, basedir, config_fname)
コード例 #42
0
    def __init__(self, basedir=u"."):
        service.MultiService.__init__(self)
        self.basedir = abspath_expanduser_unicode(unicode(basedir))
        self._portnumfile = os.path.join(self.basedir, self.PORTNUMFILE)
        fileutil.make_dirs(os.path.join(self.basedir, "private"), 0700)
        open(os.path.join(self.basedir, "private", "README"),
             "w").write(PRIV_README)

        # creates self.config
        self.read_config()
        nickname_utf8 = self.get_config("node", "nickname", "<unspecified>")
        self.nickname = nickname_utf8.decode("utf-8")
        assert type(self.nickname) is unicode

        self.init_tempdir()
        self.create_tub()
        self.logSource = "Node"

        self.setup_logging()
        self.log("Node constructed. " + get_package_versions_string())
        iputil.increase_rlimits()
コード例 #43
0
 def test_absolute_storage_dir(self):
     """
     If the ``storage_dir`` item in the ``storage`` section of the
     configuration gives an absolute path then exactly that path is used.
     """
     basedir = u"client.Basic.test_absolute_storage_dir"
     # create_client is going to try to make the storage directory so we
     # don't want a literal absolute path like /myowndir which we won't
     # have write permission to.  So construct an absolute path that we
     # should be able to write to.
     base = u"\N{SNOWMAN}"
     if encodingutil.filesystem_encoding != "utf-8":
         base = u"melted_snowman"
     expected_path = abspath_expanduser_unicode(
         u"client.Basic.test_absolute_storage_dir_myowndir/" + base)
     config_path = expected_path.encode("utf-8")
     return self._storage_dir_test(
         basedir,
         config_path,
         expected_path,
     )
コード例 #44
0
ファイル: auth.py プロジェクト: AMJ-dev/tahoe-lafs
 def __init__(self, client, accountfile):
     self.client = client
     self.passwords = BytesKeyDict()
     pubkeys = BytesKeyDict()
     self.rootcaps = BytesKeyDict()
     with open(abspath_expanduser_unicode(accountfile), "rb") as f:
         for line in f:
             line = line.strip()
             if line.startswith(b"#") or not line:
                 continue
             name, passwd, rest = line.split(None, 2)
             if passwd.startswith(b"ssh-"):
                 bits = rest.split()
                 keystring = b" ".join([passwd] + bits[:-1])
                 key = keys.Key.fromString(keystring)
                 rootcap = bits[-1]
                 pubkeys[name] = [key]
             else:
                 self.passwords[name] = passwd
                 rootcap = rest
             self.rootcaps[name] = rootcap
     self._pubkeychecker = SSHPublicKeyChecker(InMemorySSHKeyDB(pubkeys))
コード例 #45
0
ファイル: no_network.py プロジェクト: tahoe-lafs/tahoe-lafs
def create_no_network_client(basedir):
    """
    :return: a Deferred yielding an instance of _Client subclass which
        does no actual networking but has the same API.
    """
    basedir = abspath_expanduser_unicode(unicode(basedir))
    fileutil.make_dirs(os.path.join(basedir, "private"), 0o700)

    from allmydata.client import read_config
    config = read_config(basedir, u'client.port')
    storage_broker = NoNetworkStorageBroker()
    client = _NoNetworkClient(
        config,
        main_tub=None,
        i2p_provider=None,
        tor_provider=None,
        introducer_clients=[],
        storage_farm_broker=storage_broker,
    )
    # this is a (pre-existing) reference-cycle and also a bad idea, see:
    # https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2949
    storage_broker.client = client
    return defer.succeed(client)
コード例 #46
0
    def test_create_long_path(self):
        """
        Even for paths with total length greater than 260 bytes,
        ``fileutil.abspath_expanduser_unicode`` produces a path on which other
        path-related APIs can operate.

        https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
        documents certain Windows-specific path length limitations this test
        is specifically intended to demonstrate can be overcome.
        """
        workdir = u"test_create_long_path"
        fileutil.make_dirs(workdir)
        base_path = fileutil.abspath_expanduser_unicode(workdir)
        base_length = len(base_path)

        # Construct a path /just/ long enough to exercise the important case.
        # It would be nice if we could just use a seemingly globally valid
        # long file name (the `x...` portion) here - for example, a name 255
        # bytes long- and a previous version of this test did just that.
        # However, aufs imposes a 242 byte length limit on file names.  Most
        # other POSIX filesystems do allow names up to 255 bytes.  It's not
        # clear there's anything we can *do* about lower limits, though, and
        # POSIX.1-2017 (and earlier) only requires that the maximum be at
        # least 14 (!!!)  bytes.
        long_path = os.path.join(base_path, u'x' * (261 - base_length))

        def _cleanup():
            fileutil.remove(long_path)

        self.addCleanup(_cleanup)

        fileutil.write(long_path, b"test")
        self.failUnless(os.path.exists(long_path))
        self.failUnlessEqual(fileutil.read(long_path), b"test")
        _cleanup()
        self.failIf(os.path.exists(long_path))
コード例 #47
0
ファイル: node.py プロジェクト: Icy-Tywin/tahoe-lafs
    def __init__(self, configparser, portnum_fname, basedir, config_fname):
        """
        :param configparser: a ConfigParser instance

        :param portnum_fname: filename to use for the port-number file
           (a relative path inside basedir)

        :param basedir: path to our "node directory", inside which all
           configuration is managed

        :param config_fname: the pathname actually used to create the
            configparser (might be 'fake' if using in-memory data)
        """
        self.portnum_fname = portnum_fname
        self._basedir = abspath_expanduser_unicode(unicode(basedir))
        self._config_fname = config_fname
        self.config = configparser

        nickname_utf8 = self.get_config("node", "nickname", "<unspecified>")
        if isinstance(nickname_utf8, bytes):  # Python 2
            self.nickname = nickname_utf8.decode("utf-8")
        else:
            self.nickname = nickname_utf8
        assert type(self.nickname) is unicode
コード例 #48
0
ファイル: tahoe_backup.py プロジェクト: AMJ-dev/tahoe-lafs
    def run(self):
        options = self.options
        nodeurl = options['node-url']
        self.verbosity = 1
        if options['quiet']:
            self.verbosity = 0
        if options['verbose']:
            self.verbosity = 2
        stdout = options.stdout
        stderr = options.stderr

        start_timestamp = datetime.datetime.now()
        bdbfile = os.path.join(options["node-directory"], "private",
                               "backupdb.sqlite")
        bdbfile = abspath_expanduser_unicode(bdbfile)
        self.backupdb = backupdb.get_backupdb(bdbfile, stderr)
        if not self.backupdb:
            print("ERROR: Unable to load backup db.", file=stderr)
            return 1

        try:
            rootcap, path = get_alias(options.aliases, options.to_dir,
                                      DEFAULT_ALIAS)
        except UnknownAliasError as e:
            e.display(stderr)
            return 1
        to_url = nodeurl + "uri/%s/" % url_quote(rootcap)
        if path:
            to_url += escape_path(path)
        if not to_url.endswith("/"):
            to_url += "/"

        archives_url = to_url + "Archives/"

        archives_url = archives_url.rstrip("/")
        to_url = to_url.rstrip("/")

        # first step: make sure the target directory exists, as well as the
        # Archives/ subdirectory.
        resp = do_http("GET", archives_url + "?t=json")
        if resp.status == 404:
            resp = do_http("POST", archives_url + "?t=mkdir")
            if resp.status != 200:
                print(format_http_error("Unable to create target directory",
                                        resp),
                      file=stderr)
                return 1

        # second step: process the tree
        targets = list(
            collect_backup_targets(
                options.from_dir,
                listdir_unicode,
                self.options.filter_listdir,
            ))
        completed = run_backup(
            warn=self.warn,
            upload_file=self.upload,
            upload_directory=self.upload_directory,
            targets=targets,
            start_timestamp=start_timestamp,
            stdout=stdout,
        )
        new_backup_dircap = completed.dircap

        # third: attach the new backup to the list
        now = time_format.iso_utc(int(time.time()), sep="_") + "Z"

        put_child(archives_url, now, new_backup_dircap)
        put_child(to_url, "Latest", new_backup_dircap)
        print(completed.report(
            self.verbosity,
            self._files_checked,
            self._directories_checked,
        ),
              file=stdout)

        # The command exits with code 2 if files or directories were skipped
        if completed.any_skips():
            return 2

        # done!
        return 0
コード例 #49
0
ファイル: tahoe_cp.py プロジェクト: tahoe-lafs/tahoe-lafs
    def get_source_info(self, source_spec):
        """
        This turns an argv string into a (Local|Tahoe)(File|Directory)Source.
        """
        precondition(isinstance(source_spec, str), source_spec)
        rootcap, path_utf8 = get_alias(self.aliases, source_spec, None)
        path = path_utf8.decode("utf-8")
        # any trailing slash is removed in abspath_expanduser_unicode(), so
        # make a note of it here, to throw an error later
        had_trailing_slash = path.endswith("/")
        if rootcap == DefaultAliasMarker:
            # no alias, so this is a local file
            pathname = abspath_expanduser_unicode(path)
            name = os.path.basename(pathname)
            if not os.path.exists(pathname):
                raise MissingSourceError(source_spec,
                                         quotefn=quote_local_unicode_path)
            if os.path.isdir(pathname):
                t = LocalDirectorySource(self.progress, pathname, name)
            else:
                if had_trailing_slash:
                    raise FilenameWithTrailingSlashError(
                        source_spec, quotefn=quote_local_unicode_path)
                if not os.path.isfile(pathname):
                    raise WeirdSourceError(pathname)
                t = LocalFileSource(pathname, name)  # non-empty
        else:
            # this is a tahoe object
            url = self.nodeurl + "uri/%s" % url_quote(rootcap)
            name = None
            if path:
                if path.endswith("/"):
                    path = path[:-1]
                url += "/" + escape_path(path)
                last_slash = path.rfind(u"/")
                name = path
                if last_slash != -1:
                    name = path[last_slash + 1:]

            resp = do_http("GET", url + "?t=json")
            if resp.status == 404:
                raise MissingSourceError(source_spec)
            elif resp.status != 200:
                raise HTTPError(
                    "Error examining source %s" % quote_output(source_spec),
                    resp)
            parsed = json.loads(resp.read())
            nodetype, d = parsed
            if nodetype == "dirnode":
                t = TahoeDirectorySource(self.nodeurl, self.cache,
                                         self.progress, name)
                t.init_from_parsed(parsed)
            else:
                if had_trailing_slash:
                    raise FilenameWithTrailingSlashError(source_spec)
                writecap = to_bytes(d.get("rw_uri"))
                readcap = to_bytes(d.get("ro_uri"))
                mutable = d.get("mutable",
                                False)  # older nodes don't provide it
                t = TahoeFileSource(self.nodeurl, mutable, writecap, readcap,
                                    name)
        return t
コード例 #50
0
ファイル: common.py プロジェクト: cpelsser/tamias
import os, sys, urllib
import codecs
from twisted.python import usage
from allmydata.util.assertutil import precondition
from allmydata.util.encodingutil import unicode_to_url, quote_output, argv_to_abspath
from allmydata.util.fileutil import abspath_expanduser_unicode

_default_nodedir = None
if sys.platform == 'win32':
    from allmydata.windows import registry
    path = registry.get_base_dir_path()
    if path:
        precondition(isinstance(path, unicode), path)
        _default_nodedir = abspath_expanduser_unicode(path)

if _default_nodedir is None:
    path = abspath_expanduser_unicode(u"~/.tahoe")
    precondition(isinstance(path, unicode), path)
    _default_nodedir = path


def get_default_nodedir():
    return _default_nodedir


class BaseOptions(usage.Options):
    # unit tests can override these to point at StringIO instances
    stdin = sys.stdin
    stdout = sys.stdout
    stderr = sys.stderr
コード例 #51
0
    def test_join_failures(self):
        self.basedir = "cli/MagicFolder/create-join-failures"
        os.makedirs(self.basedir)
        self.set_up_grid(oneshare=True)
        local_dir = os.path.join(self.basedir, "magic")
        os.mkdir(local_dir)
        abs_local_dir_u = abspath_expanduser_unicode(unicode(local_dir),
                                                     long_path=False)

        self.invite_code = None
        d = self.do_create_magic_folder(0)
        d.addCallback(lambda ign: self.do_invite(0, self.alice_nickname))

        def get_invite_code_and_join((rc, stdout, stderr)):
            self.failUnlessEqual(rc, 0)
            self.invite_code = stdout.strip()
            return self.do_join(0, unicode(local_dir), self.invite_code)

        d.addCallback(get_invite_code_and_join)

        def get_caps(ign):
            self.collective_dircap, self.upload_dircap = self.get_caps_from_files(
                0)

        d.addCallback(get_caps)
        d.addCallback(
            lambda ign: self.check_joined_config(0, self.upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, abs_local_dir_u))

        def check_success(result):
            (rc, out, err) = result
            self.failUnlessEqual(rc, 0, out + err)

        def check_failure(result):
            (rc, out, err) = result
            self.failIfEqual(rc, 0)

        def leave(ign):
            return self.do_cli("magic-folder", "leave", client_num=0)

        d.addCallback(leave)
        d.addCallback(check_success)

        magic_folder_db_file = os.path.join(self.get_clientdir(i=0),
                                            u"private",
                                            u"magicfolder_default.sqlite")

        def check_join_if_file(my_file):
            fileutil.write(my_file, "my file data")
            d2 = self.do_cli("magic-folder",
                             "join",
                             self.invite_code,
                             local_dir,
                             client_num=0)
            d2.addCallback(check_failure)
            return d2

        for my_file in [magic_folder_db_file]:
            d.addCallback(lambda ign, my_file: check_join_if_file(my_file),
                          my_file)
            d.addCallback(leave)
            # we didn't successfully join, so leaving should be an error
            d.addCallback(check_failure)

        return d
コード例 #52
0
ファイル: encodingutil.py プロジェクト: sloanyang/tahoe-lafs
def argv_to_abspath(s):
    """
    Convenience function to decode an argv element to an absolute path, with ~ expanded.
    If this fails, raise a UsageError.
    """
    return abspath_expanduser_unicode(argv_to_unicode(s))
コード例 #53
0
    def setup_alice_and_bob(self, alice_clock=reactor, bob_clock=reactor):
        self.set_up_grid(num_clients=2, oneshare=True)

        self.alice_magicfolder = None
        self.bob_magicfolder = None

        alice_magic_dir = abspath_expanduser_unicode(u"Alice-magic",
                                                     base=self.basedir)
        self.mkdir_nonascii(alice_magic_dir)
        bob_magic_dir = abspath_expanduser_unicode(u"Bob-magic",
                                                   base=self.basedir)
        self.mkdir_nonascii(bob_magic_dir)

        # Alice creates a Magic Folder, invites herself and joins.
        d = self.do_create_magic_folder(0)
        d.addCallback(lambda ign: self.do_invite(0, self.alice_nickname))

        def get_invite_code(result):
            self.invite_code = result[1].strip()

        d.addCallback(get_invite_code)
        d.addCallback(
            lambda ign: self.do_join(0, alice_magic_dir, self.invite_code))

        def get_alice_caps(ign):
            self.alice_collective_dircap, self.alice_upload_dircap = self.get_caps_from_files(
                0)

        d.addCallback(get_alice_caps)
        d.addCallback(
            lambda ign: self.check_joined_config(0, self.alice_upload_dircap))
        d.addCallback(lambda ign: self.check_config(0, alice_magic_dir))

        def get_Alice_magicfolder(result):
            self.alice_magicfolder = self.init_magicfolder(
                0, self.alice_upload_dircap, self.alice_collective_dircap,
                alice_magic_dir, alice_clock)
            return result

        d.addCallback(get_Alice_magicfolder)

        # Alice invites Bob. Bob joins.
        d.addCallback(lambda ign: self.do_invite(0, self.bob_nickname))

        def get_invite_code(result):
            self.invite_code = result[1].strip()

        d.addCallback(get_invite_code)
        d.addCallback(
            lambda ign: self.do_join(1, bob_magic_dir, self.invite_code))

        def get_bob_caps(ign):
            self.bob_collective_dircap, self.bob_upload_dircap = self.get_caps_from_files(
                1)

        d.addCallback(get_bob_caps)
        d.addCallback(
            lambda ign: self.check_joined_config(1, self.bob_upload_dircap))
        d.addCallback(lambda ign: self.check_config(1, bob_magic_dir))

        def get_Bob_magicfolder(result):
            self.bob_magicfolder = self.init_magicfolder(
                1, self.bob_upload_dircap, self.bob_collective_dircap,
                bob_magic_dir, bob_clock)
            return result

        d.addCallback(get_Bob_magicfolder)
        return d
コード例 #54
0
def ensure_text_and_abspath_expanduser_unicode(basedir):
    # type: (Union[bytes, str]) -> str
    return abspath_expanduser_unicode(ensure_text(basedir))
コード例 #55
0
 def setUp(self):
     self.account_file = filepath.FilePath(self.mktemp())
     self.account_file.setContent(DUMMY_ACCOUNTS)
     abspath = abspath_expanduser_unicode(str(self.account_file.path))
     self.checker = auth.AccountFileChecker(None, abspath)
コード例 #56
0
ファイル: auth.py プロジェクト: tahoe-lafs/tahoe-lafs
 def __init__(self, client, accountfile):
     self.client = client
     path = abspath_expanduser_unicode(accountfile)
     with open_account_file(path) as f:
         self.rootcaps, pubkeys = load_account_file(f)
     self._pubkeychecker = SSHPublicKeyChecker(InMemorySSHKeyDB(pubkeys))
コード例 #57
0
    def test_abspath_expanduser_unicode(self):
        self.failUnlessRaises(AssertionError,
                              fileutil.abspath_expanduser_unicode,
                              b"bytestring")

        saved_cwd = os.path.normpath(os.getcwd())
        if PY2:
            saved_cwd = saved_cwd.decode("utf8")
        abspath_cwd = fileutil.abspath_expanduser_unicode(u".")
        abspath_cwd_notlong = fileutil.abspath_expanduser_unicode(
            u".", long_path=False)
        self.failUnless(isinstance(saved_cwd, str), saved_cwd)
        self.failUnless(isinstance(abspath_cwd, str), abspath_cwd)
        if sys.platform == "win32":
            self.failUnlessReallyEqual(
                abspath_cwd, fileutil.to_windows_long_path(saved_cwd))
        else:
            self.failUnlessReallyEqual(abspath_cwd, saved_cwd)
        self.failUnlessReallyEqual(abspath_cwd_notlong, saved_cwd)

        self.failUnlessReallyEqual(
            fileutil.to_windows_long_path(u"\\\\?\\foo"), u"\\\\?\\foo")
        self.failUnlessReallyEqual(
            fileutil.to_windows_long_path(u"\\\\.\\foo"), u"\\\\.\\foo")
        self.failUnlessReallyEqual(
            fileutil.to_windows_long_path(u"\\\\server\\foo"),
            u"\\\\?\\UNC\\server\\foo")
        self.failUnlessReallyEqual(fileutil.to_windows_long_path(u"C:\\foo"),
                                   u"\\\\?\\C:\\foo")
        self.failUnlessReallyEqual(
            fileutil.to_windows_long_path(u"C:\\foo/bar"),
            u"\\\\?\\C:\\foo\\bar")

        # adapted from <http://svn.python.org/view/python/branches/release26-maint/Lib/test/test_posixpath.py?view=markup&pathrev=78279#test_abspath>

        foo = fileutil.abspath_expanduser_unicode(u"foo")
        self.failUnless(foo.endswith(u"%sfoo" % (os.path.sep, )), foo)

        foobar = fileutil.abspath_expanduser_unicode(u"bar", base=foo)
        self.failUnless(
            foobar.endswith(u"%sfoo%sbar" % (os.path.sep, os.path.sep)),
            foobar)

        if sys.platform == "win32":
            # This is checking that a drive letter is added for a path without one.
            baz = fileutil.abspath_expanduser_unicode(u"\\baz")
            self.failUnless(baz.startswith(u"\\\\?\\"), baz)
            self.failUnlessReallyEqual(baz[5:], u":\\baz")

            bar = fileutil.abspath_expanduser_unicode(u"\\bar", base=baz)
            self.failUnless(bar.startswith(u"\\\\?\\"), bar)
            self.failUnlessReallyEqual(bar[5:], u":\\bar")
            # not u":\\baz\\bar", because \bar is absolute on the current drive.

            self.failUnlessReallyEqual(baz[4], bar[4])  # same drive

            baz_notlong = fileutil.abspath_expanduser_unicode(u"\\baz",
                                                              long_path=False)
            self.failIf(baz_notlong.startswith(u"\\\\?\\"), baz_notlong)
            self.failUnlessReallyEqual(baz_notlong[1:], u":\\baz")

            bar_notlong = fileutil.abspath_expanduser_unicode(u"\\bar",
                                                              base=baz_notlong,
                                                              long_path=False)
            self.failIf(bar_notlong.startswith(u"\\\\?\\"), bar_notlong)
            self.failUnlessReallyEqual(bar_notlong[1:], u":\\bar")
            # not u":\\baz\\bar", because \bar is absolute on the current drive.

            self.failUnlessReallyEqual(baz_notlong[0],
                                       bar_notlong[0])  # same drive

        self.failIfIn(u"~", fileutil.abspath_expanduser_unicode(u"~"))
        self.failIfIn(
            u"~", fileutil.abspath_expanduser_unicode(u"~", long_path=False))

        cwds = ['cwd']
        try:
            cwds.append(u'\xe7w\xf0'.encode(sys.getfilesystemencoding()
                                            or 'ascii'))
        except UnicodeEncodeError:
            pass  # the cwd can't be encoded -- test with ascii cwd only

        for cwd in cwds:
            try:
                os.mkdir(cwd)
                os.chdir(cwd)
                for upath in (u'', u'fuu', u'f\xf9\xf9', u'/fuu', u'U:\\',
                              u'~'):
                    uabspath = fileutil.abspath_expanduser_unicode(upath)
                    self.failUnless(isinstance(uabspath, str), uabspath)

                    uabspath_notlong = fileutil.abspath_expanduser_unicode(
                        upath, long_path=False)
                    self.failUnless(isinstance(uabspath_notlong, str),
                                    uabspath_notlong)
            finally:
                os.chdir(saved_cwd)
コード例 #58
0
 def call_file(name, *args):
     ns.called = True
     self.failUnlessEqual(name,
                          abspath_expanduser_unicode(exclude_file))
     return StringIO()
コード例 #59
0
class _Config(object):
    """
    Manages configuration of a Tahoe 'node directory'.

    Note: all this code and functionality was formerly in the Node
    class; names and funtionality have been kept the same while moving
    the code. It probably makes sense for several of these APIs to
    have better names.

    :ivar ConfigParser config: The actual configuration values.

    :ivar str portnum_fname: filename to use for the port-number file (a
        relative path inside basedir).

    :ivar str _basedir: path to our "node directory", inside which all
        configuration is managed.

    :ivar (FilePath|NoneType) config_path: The path actually used to create
        the configparser (might be ``None`` if using in-memory data).

    :ivar ValidConfiguration valid_config_sections: The validator for the
        values in this configuration.
    """
    config = attr.ib(
        validator=attr.validators.instance_of(configparser.ConfigParser))
    portnum_fname = attr.ib()
    _basedir = attr.ib(converter=lambda basedir: abspath_expanduser_unicode(
        ensure_text(basedir)), )
    config_path = attr.ib(validator=attr.validators.optional(
        attr.validators.instance_of(FilePath), ), )
    valid_config_sections = attr.ib(
        default=configutil.ValidConfiguration.everything(),
        validator=attr.validators.instance_of(configutil.ValidConfiguration),
    )

    @property
    def nickname(self):
        nickname = self.get_config("node", "nickname", u"<unspecified>")
        assert isinstance(nickname, str)
        return nickname

    @property
    def _config_fname(self):
        if self.config_path is None:
            return "<string>"
        return self.config_path.path

    def write_config_file(self, name, value, mode="w"):
        """
        writes the given 'value' into a file called 'name' in the config
        directory
        """
        fn = os.path.join(self._basedir, name)
        try:
            fileutil.write(fn, value, mode)
        except EnvironmentError:
            log.err(
                Failure(),
                "Unable to write config file '{}'".format(fn),
            )

    def items(self, section, default=_None):
        try:
            return self.config.items(section)
        except configparser.NoSectionError:
            if default is _None:
                raise
            return default

    def get_config(self, section, option, default=_None, boolean=False):
        try:
            if boolean:
                return self.config.getboolean(section, option)

            item = self.config.get(section, option)
            if option.endswith(".furl") and '#' in item:
                raise UnescapedHashError(section, option, item)

            return item
        except (configparser.NoOptionError, configparser.NoSectionError):
            if default is _None:
                raise MissingConfigEntry(
                    "{} is missing the [{}]{} entry".format(
                        quote_output(self._config_fname),
                        section,
                        option,
                    ))
            return default

    def set_config(self, section, option, value):
        """
        Set a config option in a section and re-write the tahoe.cfg file

        :param str section: The name of the section in which to set the
            option.

        :param str option: The name of the option to set.

        :param str value: The value of the option.

        :raise UnescapedHashError: If the option holds a fURL and there is a
            ``#`` in the value.
        """
        if option.endswith(".furl") and "#" in value:
            raise UnescapedHashError(section, option, value)

        copied_config = configutil.copy_config(self.config)
        configutil.set_config(copied_config, section, option, value)
        configutil.validate_config(
            self._config_fname,
            copied_config,
            self.valid_config_sections,
        )
        if self.config_path is not None:
            configutil.write_config(self.config_path, copied_config)
        self.config = copied_config

    def get_config_from_file(self, name, required=False):
        """Get the (string) contents of a config file, or None if the file
        did not exist. If required=True, raise an exception rather than
        returning None. Any leading or trailing whitespace will be stripped
        from the data."""
        fn = os.path.join(self._basedir, name)
        try:
            return fileutil.read(fn).strip()
        except EnvironmentError as e:
            if e.errno != errno.ENOENT:
                raise  # we only care about "file doesn't exist"
            if not required:
                return None
            raise

    def get_or_create_private_config(self, name, default=_None):
        """Try to get the (string) contents of a private config file (which
        is a config file that resides within the subdirectory named
        'private'), and return it. Any leading or trailing whitespace will be
        stripped from the data.

        If the file does not exist, and default is not given, report an error.
        If the file does not exist and a default is specified, try to create
        it using that default, and then return the value that was written.
        If 'default' is a string, use it as a default value. If not, treat it
        as a zero-argument callable that is expected to return a string.
        """
        privname = os.path.join(self._basedir, "private", name)
        try:
            value = fileutil.read(privname, mode="r")
        except EnvironmentError as e:
            if e.errno != errno.ENOENT:
                raise  # we only care about "file doesn't exist"
            if default is _None:
                raise MissingConfigEntry(
                    "The required configuration file %s is missing." %
                    (quote_output(privname), ))
            if isinstance(default, bytes):
                default = str(default, "utf-8")
            if isinstance(default, str):
                value = default
            else:
                value = default()
            fileutil.write(privname, value)
        return value.strip()

    def write_private_config(self, name, value):
        """Write the (string) contents of a private config file (which is a
        config file that resides within the subdirectory named 'private'), and
        return it.
        """
        if isinstance(value, str):
            value = value.encode("utf-8")
        privname = os.path.join(self._basedir, "private", name)
        with open(privname, "wb") as f:
            f.write(value)

    def get_private_config(self, name, default=_None):
        """Read the (native string) contents of a private config file (a
        config file that resides within the subdirectory named 'private'),
        and return it. Return a default, or raise an error if one was not
        given.
        """
        privname = os.path.join(self._basedir, "private", name)
        try:
            return fileutil.read(privname, mode="r").strip()
        except EnvironmentError as e:
            if e.errno != errno.ENOENT:
                raise  # we only care about "file doesn't exist"
            if default is _None:
                raise MissingConfigEntry(
                    "The required configuration file %s is missing." %
                    (quote_output(privname), ))
            return default

    def get_private_path(self, *args):
        """
        returns an absolute path inside the 'private' directory with any
        extra args join()-ed
        """
        return os.path.join(self._basedir, "private", *args)

    def get_config_path(self, *args):
        """
        returns an absolute path inside the config directory with any
        extra args join()-ed
        """
        # note: we re-expand here (_basedir already went through this
        # expanduser function) in case the path we're being asked for
        # has embedded ".."'s in it
        return abspath_expanduser_unicode(os.path.join(self._basedir, *args))

    def get_introducer_configuration(self):
        """
        Get configuration for introducers.

        :return {unicode: (unicode, FilePath)}: A mapping from introducer
            petname to a tuple of the introducer's fURL and local cache path.
        """
        introducers_yaml_filename = self.get_private_path("introducers.yaml")
        introducers_filepath = FilePath(introducers_yaml_filename)

        def get_cache_filepath(petname):
            return FilePath(
                self.get_private_path(
                    "introducer_{}_cache.yaml".format(petname)), )

        try:
            with introducers_filepath.open() as f:
                introducers_yaml = safe_load(f)
                if introducers_yaml is None:
                    raise EnvironmentError(
                        EPERM,
                        "Can't read '{}'".format(introducers_yaml_filename),
                        introducers_yaml_filename,
                    )
                introducers = {
                    petname: config["furl"]
                    for petname, config in introducers_yaml.get(
                        "introducers", {}).items()
                }
                non_strs = list(k for k in introducers.keys()
                                if not isinstance(k, str))
                if non_strs:
                    raise TypeError(
                        "Introducer petnames {!r} should have been str".format(
                            non_strs, ), )
                non_strs = list(v for v in introducers.values()
                                if not isinstance(v, str))
                if non_strs:
                    raise TypeError(
                        "Introducer fURLs {!r} should have been str".format(
                            non_strs, ), )
                log.msg("found {} introducers in {!r}".format(
                    len(introducers),
                    introducers_yaml_filename,
                ))
        except EnvironmentError as e:
            if e.errno != ENOENT:
                raise
            introducers = {}

        # supported the deprecated [client]introducer.furl item in tahoe.cfg
        tahoe_cfg_introducer_furl = self.get_config("client",
                                                    "introducer.furl", None)
        if tahoe_cfg_introducer_furl == "None":
            raise ValueError("tahoe.cfg has invalid 'introducer.furl = None':"
                             " to disable it omit the key entirely")
        if tahoe_cfg_introducer_furl:
            warn(
                "tahoe.cfg [client]introducer.furl is deprecated; "
                "use private/introducers.yaml instead.",
                category=DeprecationWarning,
                stacklevel=-1,
            )
            if "default" in introducers:
                raise ValueError(
                    "'default' introducer furl cannot be specified in tahoe.cfg and introducers.yaml;"
                    " please fix impossible configuration.")
            introducers['default'] = tahoe_cfg_introducer_furl

        return {
            petname: (furl, get_cache_filepath(petname))
            for (petname, furl) in introducers.items()
        }
コード例 #60
0
    def check_file(self, path, use_timestamps=True):
        """I will tell you if a given local file needs to be uploaded or not,
        by looking in a database and seeing if I have a record of this file
        having been uploaded earlier.

        I return a FileResults object, synchronously. If r.was_uploaded()
        returns False, you should upload the file. When you are finished
        uploading it, call r.did_upload(filecap), so I can update my
        database.

        If was_uploaded() returns a filecap, you might be able to avoid an
        upload. Call r.should_check(), and if it says False, you can skip the
        upload and use the filecap returned by was_uploaded().

        If should_check() returns True, you should perform a filecheck on the
        filecap returned by was_uploaded(). If the check indicates the file
        is healthy, please call r.did_check_healthy(checker_results) so I can
        update the database, using the de-JSONized response from the webapi
        t=check call for 'checker_results'. If the check indicates the file
        is not healthy, please upload the file and call r.did_upload(filecap)
        when you're done.

        I use_timestamps=True (the default), I will compare ctime and mtime
        of the local file against an entry in my database, and consider the
        file to be unchanged if ctime, mtime, and filesize are all the same
        as the earlier version. If use_timestamps=False, I will not trust the
        timestamps, so more files (perhaps all) will be marked as needing
        upload. A future version of this database may hash the file to make
        equality decisions, in which case use_timestamps=False will not
        always imply r.must_upload()==True.

        'path' points to a local file on disk, possibly relative to the
        current working directory. The database stores absolute pathnames.
        """

        path = abspath_expanduser_unicode(path)
        s = os.stat(path)
        size = s[stat.ST_SIZE]
        ctime = s[stat.ST_CTIME]
        mtime = s[stat.ST_MTIME]

        now = time.time()
        c = self.cursor

        c.execute(
            "SELECT size,mtime,ctime,fileid"
            " FROM local_files"
            " WHERE path=?", (path, ))
        row = self.cursor.fetchone()
        if not row:
            return FileResult(self, None, False, path, mtime, ctime, size)
        (last_size, last_mtime, last_ctime, last_fileid) = row

        c.execute(
            "SELECT caps.filecap, last_upload.last_checked"
            " FROM caps,last_upload"
            " WHERE caps.fileid=? AND last_upload.fileid=?",
            (last_fileid, last_fileid))
        row2 = c.fetchone()

        if ((last_size != size or not use_timestamps or last_mtime != mtime
             or last_ctime != ctime)  # the file has been changed
                or
            (not row2)  # we somehow forgot where we put the file last time
            ):
            c.execute("DELETE FROM local_files WHERE path=?", (path, ))
            self.connection.commit()
            return FileResult(self, None, False, path, mtime, ctime, size)

        # at this point, we're allowed to assume the file hasn't been changed
        (filecap, last_checked) = row2
        age = now - last_checked

        probability = ((age - self.NO_CHECK_BEFORE) /
                       (self.ALWAYS_CHECK_AFTER - self.NO_CHECK_BEFORE))
        probability = min(max(probability, 0.0), 1.0)
        should_check = bool(random.random() < probability)

        return FileResult(self, to_str(filecap), should_check, path, mtime,
                          ctime, size)