[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [chutney/master] TorNet: replace os.path calls with pathlib



commit 3c1a744dd0949f4debea46aeb4e3c3dc88a13db4
Author: c <c@xxxxxxxxxxx>
Date:   Sun Jul 5 07:59:18 2020 +0000

    TorNet: replace os.path calls with pathlib
    
    Part of <https://gitlab.torproject.org/tpo/core/chutney/-/issues/40002>
    to ensure consistency of code dealing with file paths
---
 lib/chutney/TorNet.py | 121 +++++++++++++++++++++++++-------------------------
 1 file changed, 60 insertions(+), 61 deletions(-)

diff --git a/lib/chutney/TorNet.py b/lib/chutney/TorNet.py
index df3c33d..fb2b8a4 100644
--- a/lib/chutney/TorNet.py
+++ b/lib/chutney/TorNet.py
@@ -12,6 +12,8 @@ from __future__ import division
 from __future__ import print_function
 from __future__ import unicode_literals
 
+from pathlib import Path
+
 import cgitb
 import errno
 import importlib
@@ -134,8 +136,8 @@ def get_absolute_chutney_path():
     # (./chutney already sets CHUTNEY_PATH using the path to the script)
     # use tools/test-network.sh if you want chutney to try really hard to find
     # itself
-    relative_chutney_path = os.environ.get('CHUTNEY_PATH', os.getcwd())
-    return os.path.abspath(relative_chutney_path)
+    relative_chutney_path = Path(os.environ.get('CHUTNEY_PATH', os.getcwd()))
+    return relative_chutney_path.resolve()
 
 def get_absolute_net_path():
     """
@@ -153,23 +155,23 @@ def get_absolute_net_path():
        Finally, return the path relative to the current working directory,
        regardless of whether the path actually exists.
     """
-    data_dir = os.environ.get('CHUTNEY_DATA_DIR', 'net')
-    if os.path.isabs(data_dir):
+    data_dir = Path(os.environ.get('CHUTNEY_DATA_DIR', 'net'))
+    if data_dir.is_absolute():
         # if we are given an absolute path, we should use it
         # regardless of whether the directory exists
         return data_dir
     # use the chutney path as the default
     absolute_chutney_path = get_absolute_chutney_path()
-    relative_net_path = data_dir
+    relative_net_path = Path(data_dir)
     # but what is it relative to?
     # let's check if there's an existing directory with this name in
     # CHUTNEY_PATH first, to preserve backwards-compatible behaviour
-    chutney_net_path = os.path.join(absolute_chutney_path, relative_net_path)
-    if os.path.isdir(chutney_net_path):
+    chutney_net_path = Path(absolute_chutney_path, relative_net_path)
+    if chutney_net_path.is_dir():
         return chutney_net_path
     # ok, it's relative to the current directory, whatever that is, and whether
     # or not the path actually exists
-    return os.path.abspath(relative_net_path)
+    return relative_net_path.resolve()
 
 def get_absolute_nodes_path():
     """
@@ -182,7 +184,7 @@ def get_absolute_nodes_path():
 
        See get_new_absolute_nodes_path() for more details.
     """
-    return os.path.join(get_absolute_net_path(), 'nodes')
+    return Path(get_absolute_net_path(), 'nodes')
 
 def get_new_absolute_nodes_path(now=time.time()):
     """
@@ -202,12 +204,12 @@ def get_new_absolute_nodes_path(now=time.time()):
     # should only be called by 'chutney configure', all other chutney commands
     # should use get_absolute_nodes_path()
     nodesdir = get_absolute_nodes_path()
-    newdir = newdirbase = "%s.%d" % (nodesdir, now)
+    newdir = newdirbase = Path("%s.%d" % (nodesdir, now))
     # if the time is the same, fall back to a simple integer count
     # (this is very unlikely to happen unless the clock changes: it's not
     # possible to run multiple chutney networks at the same time)
     i = 0
-    while os.path.exists(newdir):
+    while newdir.exists():
         i += 1
         newdir = "%s.%d" % (newdirbase, i)
     return newdir
@@ -735,12 +737,12 @@ class LocalNodeBuilder(NodeBuilder):
         datadir = self._env['dir']
         tor_gencert = self._env['tor_gencert']
         lifetime = self._env['auth_cert_lifetime']
-        idfile = os.path.join(datadir, 'keys', "authority_identity_key")
-        skfile = os.path.join(datadir, 'keys', "authority_signing_key")
-        certfile = os.path.join(datadir, 'keys', "authority_certificate")
+        idfile = Path(datadir, 'keys', "authority_identity_key")
+        skfile = Path(datadir, 'keys', "authority_signing_key")
+        certfile = Path(datadir, 'keys', "authority_certificate")
         addr = self.expand("${ip}:${dirport}")
         passphrase = self._env['auth_passphrase']
-        if all(os.path.exists(f) for f in [idfile, skfile, certfile]):
+        if all(f.exists() for f in [idfile, skfile, certfile]):
             return
         cmdline = [
             tor_gencert,
@@ -790,9 +792,9 @@ class LocalNodeBuilder(NodeBuilder):
             return ""
 
         datadir = self._env['dir']
-        certfile = os.path.join(datadir, 'keys', "authority_certificate")
+        certfile = Path(datadir, 'keys', "authority_certificate")
         v3id = None
-        with open(certfile, 'r') as f:
+        with certfile.open(mode='r') as f:
             for line in f:
                 if line.startswith("fingerprint"):
                     v3id = line.split()[1].strip()
@@ -880,24 +882,23 @@ class LocalNodeController(NodeController):
            Raises a ValueError if the file appears to be corrupt.
         """
         datadir = self._env['dir']
-        key_file = os.path.join(datadir, 'keys',
-                                "ed25519_master_id_public_key")
+        key_file = Path(datadir, 'keys', 'ed25519_master_id_public_key')
         # If we're called early during bootstrap, the file won't have been
         # created yet. (And some very old tor versions don't have ed25519.)
-        if not os.path.exists(key_file):
+        if not key_file.exists():
             debug(("File {} does not exist. Are you running a very old tor "
                    "version?").format(key_file))
             return None
 
         EXPECTED_ED25519_FILE_SIZE = 64
-        key_file_size = os.stat(key_file).st_size
+        key_file_size = key_file.stat().st_size
         if key_file_size != EXPECTED_ED25519_FILE_SIZE:
             raise ValueError(
                 ("The current size of the file is {} bytes, which is not"
                  "matching the expected value of {} bytes")
                 .format(key_file_size, EXPECTED_ED25519_FILE_SIZE))
 
-        with open(key_file, 'rb') as f:
+        with key_file.open(mode='rb') as f:
             ED25519_KEY_POSITION = 32
             f.seek(ED25519_KEY_POSITION)
             rest_file = f.read()
@@ -1061,11 +1062,11 @@ class LocalNodeController(NodeController):
         """Read the pidfile, and return the pid of the running process.
            Returns None if there is no pid in the file.
         """
-        pidfile = self._env['pidfile']
-        if not os.path.exists(pidfile):
+        pidfile = Path(self._env['pidfile'])
+        if not pidfile.exists():
             return None
 
-        with open(pidfile, 'r') as f:
+        with pidfile.open(mode='r') as f:
             try:
                 return int(f.read())
             except ValueError:
@@ -1113,7 +1114,7 @@ class LocalNodeController(NodeController):
                 print("{:12} is running with PID {:5}: {}"
                       .format(nick, pid, tor_version))
             return True
-        elif corefile and os.path.exists(os.path.join(datadir, corefile)):
+        elif corefile and Path(datadir, corefile).exists():
             if listNonRunning:
                 print("{:12} seems to have crashed, and left core file {}: {}"
                       .format(nick, corefile, tor_version))
@@ -1197,8 +1198,8 @@ class LocalNodeController(NodeController):
 
     def cleanup_lockfile(self):
         """Remove lock file if this node is no longer running."""
-        lf = self._env['lockfile']
-        if not self.isRunning() and os.path.exists(lf):
+        lf = Path(self._env['lockfile'])
+        if not self.isRunning() and lf.exists():
             debug("Removing stale lock file for {} ..."
                   .format(self._env['nick']))
             os.remove(lf)
@@ -1207,8 +1208,8 @@ class LocalNodeController(NodeController):
         """Move PID file to pidfile.old if this node is no longer running
            so that we don't try to stop the node again.
         """
-        pidfile = self._env['pidfile']
-        if not self.isRunning() and os.path.exists(pidfile):
+        pidfile = Path(self._env['pidfile'])
+        if not self.isRunning() and pidfile.exists():
             debug("Renaming stale pid file for {} ..."
                   .format(self._env['nick']))
             os.rename(pidfile, pidfile + ".old")
@@ -1249,7 +1250,7 @@ class LocalNodeController(NodeController):
             logname = "info.log"
         else:
             logname = "notice.log"
-        return os.path.join(datadir, logname)
+        return Path(datadir, logname)
 
     INTERNAL_ERROR_CODE = -500
     MISSING_FILE_CODE = -400
@@ -1265,13 +1266,13 @@ class LocalNodeController(NodeController):
            (optional), and message.
         """
         logfname = self.getLogfile()
-        if not os.path.exists(logfname):
+        if not logfname.exists():
             return (LocalNodeController.MISSING_FILE_CODE,
                     "no_logfile", "There is no logfile yet.")
         percent = LocalNodeController.NO_RECORDS_CODE
         keyword = "no_message"
         message = "No bootstrap messages yet."
-        with open(logfname, 'r') as f:
+        with logfname.open(mode='r') as f:
             for line in f:
                 m = re.search(r'Bootstrapped (\d+)%(?: \(([^\)]*)\))?: (.*)',
                               line)
@@ -1326,16 +1327,15 @@ class LocalNodeController(NodeController):
         datadir = self._env['dir']
         to_dir_server = self.getDirServer()
 
-        desc = os.path.join(datadir, "cached-descriptors")
-        desc_new = os.path.join(datadir, "cached-descriptors.new")
+        desc = Path(datadir, "cached-descriptors")
+        desc_new = Path(datadir, "cached-descriptors.new")
 
         paths = None
         if v2_dir_paths:
-            ns_cons = os.path.join(datadir, "cached-consensus")
-            md_cons = os.path.join(datadir,
-                                           "cached-microdesc-consensus")
-            md = os.path.join(datadir, "cached-microdescs")
-            md_new = os.path.join(datadir, "cached-microdescs.new")
+            ns_cons = Path(datadir, "cached-consensus")
+            md_cons = Path(datadir, "cached-microdesc-consensus")
+            md = Path(datadir, "cached-microdescs")
+            md_new = Path(datadir, "cached-microdescs.new")
 
             paths = { 'ns_cons': ns_cons,
                       'desc': desc,
@@ -1354,7 +1354,7 @@ class LocalNodeController(NodeController):
             # bootstrapping, and trying to publish their descriptors too early
             if to_bridge_auth:
                 paths = None
-            #   br_status = os.path.join(datadir, "networkstatus-bridges")
+            #   br_status = Path(datadir, "networkstatus-bridges")
             #   paths['br_status'] = br_status
         else:
             # We're looking for bridges, but other nodes don't use bridges
@@ -1440,14 +1440,15 @@ class LocalNodeController(NodeController):
              * a set containing dir_format; and
              * a status message string.
         """
-        if not os.path.exists(dir_path):
+        dir_path = Path(dir_path)
+        if not dir_path.exists():
             return (LocalNodeController.MISSING_FILE_CODE,
                     { dir_format }, "No dir file")
 
         dir_pattern = self.getNodeDirInfoStatusPattern(dir_format)
 
         line_count = 0
-        with open(dir_path, 'r') as f:
+        with dir_path.open(mode='r') as f:
             for line in f:
                 line_count = line_count + 1
                 if dir_pattern:
@@ -2002,10 +2003,9 @@ class TorEnviron(chutney.Templating.Environ):
         return my['ptport_base'] + my['nodenum']
 
     def _get_dir(self, my):
-        return os.path.abspath(os.path.join(my['net_base_dir'],
-                                            "nodes",
-                                            "%03d%s" % (
-                                                my['nodenum'], my['tag'])))
+        return Path(my['net_base_dir'],
+                    "nodes",
+                    "%03d%s" % (my['nodenum'], my['tag'])).resolve()
 
     def _get_nick(self, my):
         return "test%03d%s" % (my['nodenum'], my['tag'])
@@ -2017,13 +2017,13 @@ class TorEnviron(chutney.Templating.Environ):
         return self['nick']  # OMG TEH SECURE!
 
     def _get_torrc_template_path(self, my):
-        return [os.path.join(my['chutney_dir'], 'torrc_templates')]
+        return [Path(my['chutney_dir'], 'torrc_templates')]
 
     def _get_lockfile(self, my):
-        return os.path.join(self['dir'], 'lock')
+        return Path(self['dir'], 'lock')
 
     def _get_pidfile(self, my):
-        return os.path.join(self['dir'], 'pid')
+        return Path(self['dir'], 'pid')
 
     # A hs generates its key on first run,
     # so check for it at the last possible moment,
@@ -2034,8 +2034,7 @@ class TorEnviron(chutney.Templating.Environ):
         if my['hs-hostname'] is None:
             datadir = my['dir']
             # a file containing a single line with the hs' .onion address
-            hs_hostname_file = os.path.join(datadir, my['hs_directory'],
-                                            'hostname')
+            hs_hostname_file = Path(datadir, my['hs_directory'], 'hostname')
             try:
                 with open(hs_hostname_file, 'r') as hostnamefp:
                     hostname = hostnamefp.read()
@@ -2077,11 +2076,11 @@ class TorEnviron(chutney.Templating.Environ):
             dns_conf = TorEnviron.DEFAULT_DNS_RESOLV_CONF
         else:
             dns_conf = my['dns_conf']
-        dns_conf = os.path.abspath(dns_conf)
+        dns_conf = Path(dns_conf).resolve()
         # work around Tor bug #21900, where exits fail when the DNS conf
         # file does not exist, or is a broken symlink
-        # (os.path.exists returns False for broken symbolic links)
-        if not os.path.exists(dns_conf):
+        # (Path.exists returns False for broken symbolic links)
+        if not dns_conf.exists():
             # Issue a warning so the user notices
             print("CHUTNEY_DNS_CONF '{}' does not exist, using '{}'."
                   .format(dns_conf, TorEnviron.OFFLINE_DNS_RESOLV_CONF))
@@ -2121,17 +2120,17 @@ class Network(object):
         nodesdir = get_absolute_nodes_path()
 
         # only move the directory if it exists
-        if not os.path.exists(nodesdir):
+        if not nodesdir.exists():
             return
         # and if it's not a link
-        if os.path.islink(nodesdir):
+        if nodesdir.is_symlink():
             return
 
         # subtract 1 second to avoid collisions and get the correct ordering
         newdir = get_new_absolute_nodes_path(time.time() - 1)
 
         print("NOTE: renaming %r to %r" % (nodesdir, newdir))
-        os.rename(nodesdir, newdir)
+        nodesdir.rename(newdir)
 
     def create_new_nodes_dir(self):
         """Create a new directory with a unique name, and symlink it to nodes
@@ -2146,12 +2145,12 @@ class Network(object):
         nodeslink = get_absolute_nodes_path()
 
         # this path should be unique and should not exist
-        if os.path.exists(newnodesdir):
+        if newnodesdir.exists():
             raise RuntimeError(
                 'get_new_absolute_nodes_path returned a path that exists')
 
         # if this path exists, it must be a link
-        if os.path.exists(nodeslink) and not os.path.islink(nodeslink):
+        if nodeslink.exists() and not nodeslink.is_symlink():
             raise RuntimeError(
                 'get_absolute_nodes_path returned a path that exists and '
                 'is not a link')
@@ -2161,7 +2160,7 @@ class Network(object):
         # this gets created with mode 0700, that's probably ok
         mkdir_p(newnodesdir)
         try:
-            os.unlink(nodeslink)
+            nodeslink.unlink()
         except OSError as e:
             # it's ok if the link doesn't exist, we're just about to make it
             if e.errno == errno.ENOENT:



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits