Changeset 874a979 in trunk


Ignore:
Timestamp:
2010-01-14T21:02:46Z (16 years ago)
Author:
Brian Warner <warner@…>
Branches:
master
Children:
731d15e
Parents:
d3d1293
Message:

tahoe add-alias/create-alias: don't corrupt non-newline-terminated alias
file. Closes #741.

Location:
src/allmydata
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/allmydata/scripts/tahoe_add_alias.py

    rd3d1293 r874a979  
    44from allmydata.scripts.common_http import do_http, check_http_error
    55from allmydata.scripts.common import get_aliases
     6from allmydata.util.fileutil import move_into_place
    67
    78def add_alias(options):
     
    2021    aliasfile = os.path.join(nodedir, "private", "aliases")
    2122    cap = uri.from_string_dirnode(cap).to_string()
    22     f = open(aliasfile, "a")
    23     f.write("%s: %s\n" % (alias, cap))
     23
     24    # we use os.path.exists, rather than catching EnvironmentError, to avoid
     25    # clobbering the valuable alias file in case of spurious or transient
     26    # filesystem errors.
     27    if os.path.exists(aliasfile):
     28        f = open(aliasfile, "r")
     29        aliases = f.read()
     30        f.close()
     31        if not aliases.endswith("\n"):
     32            aliases += "\n"
     33    else:
     34        aliases = ""
     35    aliases += "%s: %s\n" % (alias, cap)
     36    f = open(aliasfile+".tmp", "w")
     37    f.write(aliases)
    2438    f.close()
     39    move_into_place(aliasfile+".tmp", aliasfile)
     40
    2541    print >>stdout, "Alias '%s' added" % (alias,)
    2642    return 0
     
    5369
    5470    # probably check for others..
    55     f = open(aliasfile, "a")
    56     f.write("%s: %s\n" % (alias, new_uri))
     71
     72    # see above about EnvironmentError
     73    if os.path.exists(aliasfile):
     74        f = open(aliasfile, "r")
     75        aliases = f.read()
     76        f.close()
     77        if not aliases.endswith("\n"):
     78            aliases += "\n"
     79    else:
     80        aliases = ""
     81    aliases += "%s: %s\n" % (alias, new_uri)
     82    f = open(aliasfile+".tmp", "w")
     83    f.write(aliases)
    5784    f.close()
     85    move_into_place(aliasfile+".tmp", aliasfile)
     86
    5887    print >>stdout, "Alias '%s' created" % (alias,)
    5988    return 0
     
    6291    nodedir = options['node-directory']
    6392    stdout = options.stdout
    64     stderr = options.stderr
    6593    aliases = get_aliases(nodedir)
    6694    alias_names = sorted(aliases.keys())
  • TabularUnified src/allmydata/test/test_cli.py

    rd3d1293 r874a979  
    9999    def test_dump_cap_chk(self):
    100100        key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
    101         storage_index = hashutil.storage_index_hash(key)
    102101        uri_extension_hash = hashutil.uri_extension_hash("stuff")
    103102        needed_shares = 25
     
    461460        self.basedir = "cli/CreateAlias/create"
    462461        self.set_up_grid()
     462        aliasfile = os.path.join(self.get_clientdir(), "private", "aliases")
    463463
    464464        d = self.do_cli("create-alias", "tahoe")
     
    522522            self._test_webopen(["two:"], self.two_url)
    523523        d.addCallback(_test_urls)
     524
     525        def _remove_trailing_newline_and_create_alias(ign):
     526            f = open(aliasfile, "r")
     527            old = f.read()
     528            f.close()
     529            # ticket #741 is about a manually-edited alias file (which
     530            # doesn't end in a newline) being corrupted by a subsequent
     531            # "tahoe create-alias"
     532            f = open(aliasfile, "w")
     533            f.write(old.rstrip())
     534            f.close()
     535            return self.do_cli("create-alias", "un-corrupted1")
     536        d.addCallback(_remove_trailing_newline_and_create_alias)
     537        def _check_not_corrupted1((rc,stdout,stderr)):
     538            self.failUnless("Alias 'un-corrupted1' created" in stdout, stdout)
     539            self.failIf(stderr)
     540            # the old behavior was to simply append the new record, causing a
     541            # line that looked like "NAME1: CAP1NAME2: CAP2". This won't look
     542            # like a valid dircap, so get_aliases() will raise an exception.
     543            aliases = get_aliases(self.get_clientdir())
     544            self.failUnless("added" in aliases)
     545            self.failUnless(aliases["added"].startswith("URI:DIR2:"))
     546            # to be safe, let's confirm that we don't see "NAME2:" in CAP1.
     547            # No chance of a false-negative, because the hyphen in
     548            # "un-corrupted1" is not a valid base32 character.
     549            self.failIfIn("un-corrupted1:", aliases["added"])
     550            self.failUnless("un-corrupted1" in aliases)
     551            self.failUnless(aliases["un-corrupted1"].startswith("URI:DIR2:"))
     552        d.addCallback(_check_not_corrupted1)
     553
     554        def _remove_trailing_newline_and_add_alias(ign):
     555            # same thing, but for "tahoe add-alias"
     556            f = open(aliasfile, "r")
     557            old = f.read()
     558            f.close()
     559            f = open(aliasfile, "w")
     560            f.write(old.rstrip())
     561            f.close()
     562            return self.do_cli("add-alias", "un-corrupted2", self.two_uri)
     563        d.addCallback(_remove_trailing_newline_and_add_alias)
     564        def _check_not_corrupted((rc,stdout,stderr)):
     565            self.failUnless("Alias 'un-corrupted2' added" in stdout, stdout)
     566            self.failIf(stderr)
     567            aliases = get_aliases(self.get_clientdir())
     568            self.failUnless("un-corrupted1" in aliases)
     569            self.failUnless(aliases["un-corrupted1"].startswith("URI:DIR2:"))
     570            self.failIfIn("un-corrupted2:", aliases["un-corrupted1"])
     571            self.failUnless("un-corrupted2" in aliases)
     572            self.failUnless(aliases["un-corrupted2"].startswith("URI:DIR2:"))
     573        d.addCallback(_check_not_corrupted)
    524574
    525575        return d
     
    593643
    594644        rel_fn = os.path.join(self.basedir, "DATAFILE")
    595         abs_fn = os.path.abspath(rel_fn)
    596645        # we make the file small enough to fit in a LIT file, for speed
    597646        DATA = "short file"
     
    677726        DATA2 = "two" * 100
    678727        rel_fn = os.path.join(self.basedir, "DATAFILE")
    679         abs_fn = os.path.abspath(rel_fn)
    680728        DATA3 = "three" * 100
    681729        f = open(rel_fn, "w")
Note: See TracChangeset for help on using the changeset viewer.