gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r18557 - gnunet-update/gnunet_update


From: gnunet
Subject: [GNUnet-SVN] r18557 - gnunet-update/gnunet_update
Date: Mon, 12 Dec 2011 11:06:19 +0100

Author: harsha
Date: 2011-12-12 11:06:19 +0100 (Mon, 12 Dec 2011)
New Revision: 18557

Added:
   gnunet-update/gnunet_update/install_manifest.py
Modified:
   gnunet-update/gnunet_update/install.py
   gnunet-update/gnunet_update/update.py
   gnunet-update/gnunet_update/util.py
Log:
update module per file hash verfication

Modified: gnunet-update/gnunet_update/install.py
===================================================================
--- gnunet-update/gnunet_update/install.py      2011-12-11 15:39:53 UTC (rev 
18556)
+++ gnunet-update/gnunet_update/install.py      2011-12-12 10:06:19 UTC (rev 
18557)
@@ -30,10 +30,10 @@
 import tempfile
 
 import util
+import install_manifest
 from metadata import Metadata
 from config import GnunetUpdateConfig
 
-
 def usage():
     """Print helpful usage information."""    
     print """
@@ -123,17 +123,16 @@
     if not os.path.exists(dep_dir):
         os.makedirs(dep_dir)
     # Add the gnunet dependency dir to the install manifest
-    installed_files.append("lib/gnunet-deps")
     orig_working_dir = os.getcwd()
     # Change to dep install dir
     os.chdir(dep_dir)
 
+    installed_dep_files = list()
     for dep in to_be_installed_deps:
         dep_tarinfo = package_tarfile.getmember("dependencies/" + dep.realname)
         # Remove the `dependencies/' in member.name
         dep_tarinfo.name = dep_tarinfo.name.replace("dependencies/","",1)
         package_tarfile.extract(dep_tarinfo, "./")
-        installed_files.append(os.path.join("lib/gnunet-deps/", 
dep_tarinfo.name))
         # Check the hash of the extracted file
         if util.hexdigest(dep_tarinfo.name) != dep.hash:
             print (dep_tarinfo.name + 
@@ -144,28 +143,25 @@
             os.chdir(orig_working_dir)
             shutil.rmtree(install_dir)
             sys.exit(-1)
-        
+            
         # Generate symbolic link from dep.name to dep.realname
         # NOTE: Available only on Unix type systems!
         if os.path.exists(dep.name):
             os.remove(dep.name)
         os.symlink(dep.realname, dep.name)
-        installed_files.append(os.path.join("lib/gnunet-deps", dep.name))
+        installed_dep_files.append(dep)
+
     package_tarfile.close()
 
     # run ldconfig -n in the dep_dir
-    proc = subprocess.Popen(["ldconfig", "-n"])
-    proc.wait()
-    os.chdir(orig_working_dir)
+    # proc = subprocess.Popen(["ldconfig", "-n"])
+    # proc.wait()
+    # os.chdir(orig_working_dir)
 
     # Write install manifest file
-    if not os.path.exists(os.path.join(install_dir, "share/gnunet-update/")):
-        os.makedirs(os.path.join(install_dir, "share/gnunet-update/"))
-    install_manifest_fd = open(os.path.join(install_dir,
-                                            
"share/gnunet-update/install-manifest"),
-                               "wb") 
-    map((lambda name: install_manifest_fd.write(name + '\n')), installed_files)
-    install_manifest_fd.close()
+    install_manifest.write_to_file(install_dir, 
+                                   installed_files,
+                                   installed_dep_files)
     print "Installation Successful!"
     print "GNUNET has been installed at: " + install_dir
     shared_library_setup([os.path.join(install_dir, "lib"), 

Added: gnunet-update/gnunet_update/install_manifest.py
===================================================================
--- gnunet-update/gnunet_update/install_manifest.py                             
(rev 0)
+++ gnunet-update/gnunet_update/install_manifest.py     2011-12-12 10:06:19 UTC 
(rev 18557)
@@ -0,0 +1,113 @@
+# This file is part of GNUnet.
+# (C) 2001--2011 Christian Grothoff (and other contributing authors)
+#
+# GNUnet is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; either version 2, or (at your
+# option) any later version.
+#
+# GNUnet is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNUnet; see the file COPYING.  If not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+#File:     gnunet_update/install_manifest.py
+#Author:   Sree Harsha Totakura
+#
+# Handles install-manifest files
+
+import os
+
+from file import FileObject
+
+
+"""Class for holding install manifest information."""
+install_manifest_file_path = "share/gnunet-update/install-manifest"
+
+def write_to_file(install_dir, file_objects, dep_objects):
+    """Writes the contents of file_objects to a file in install_base_dir. Only
+    the object name and hash are stored. Object path is not stored.
+    
+    install_dir: The base directory where the software is installed
+        file_objects: A list of FileEntity Objects having a name and hash
+        value
+    file_objects: The file objects which are to be written to the install
+        manifest file
+    dep_objects: The dependency objects which are to be included in the install
+        manifest file
+    """
+    # Create the directory which holds install manifest file if not present
+    install_manifest_file_dir = os.path.dirname(install_manifest_file_path)
+    if not os.path.exists(os.path.join(install_dir,
+                                       install_manifest_file_dir)):
+        
+        os.makedirs(os.path.join(install_dir,
+                                 install_manifest_file_dir))
+        
+    f = open(os.path.join(install_dir,
+                          install_manifest_file_path),
+             "wb")
+
+    map(lambda file_object: 
+        f.write(file_object.name + ";" + file_object.hash + "\n"),
+        file_objects)
+
+    f.write("%%\n")            # The section seperator
+    map(lambda dep_object:
+            f.write(dep_object.name + ";" + dep_object.realname 
+                    + ";" + dep_object.hash + '\n'),
+        dep_objects)
+        
+    f.close()
+
+def read_from_file(install_dir):
+    """
+    Reads the install manifest file in install dir directory and returns
+    the file entities as a list. The manifest file contains only object's name
+    and hash. The object's path is however calculated at the runtime from the
+    object's name and install_dir
+    
+    install_dir: The base directory where the software is installed 
+    return: A tuple containing list of FileEntity instances corresponding to
+        each file entity present in the install manifest file and dependency
+        objects 
+    """
+    
+    f = open(os.path.join(install_dir,
+                          install_manifest_file_path),
+             "rb")
+    file_objects = list()   # List to hold the file objects
+    while True:
+        read_line = f.readline()
+        if read_line == "%%\n": # Section seperator
+            break
+        tokens = read_line.split(';')
+        rel_file_path = tokens[0]
+        file_hash = tokens[1]
+        file_object = FileObject(os.path.basename(rel_file_path),
+                                 os.path.join(install_dir,
+                                              rel_file_path),
+                                 file_hash)
+        file_objects.append(file_object)
+    
+    dep_objects = list()
+    while True:
+        read_line = f.readline()
+        if len(read_line) == 0: # Reached EOF?
+            break
+        tokens = read_line.split(';')
+        dep_name = tokens[0]
+        dep_realname = tokens[1]
+        dep_hash = tokens[2]
+        dep_object = DependencyFileObject(dep_name,
+                                          None,
+                                          dep_hash)
+        dep_object.realname = dep_realname
+        dep_objects.append(dep_object)
+    f.close()
+    return (file_objects, dep_objects)

Modified: gnunet-update/gnunet_update/update.py
===================================================================
--- gnunet-update/gnunet_update/update.py       2011-12-11 15:39:53 UTC (rev 
18556)
+++ gnunet-update/gnunet_update/update.py       2011-12-12 10:06:19 UTC (rev 
18557)
@@ -44,6 +44,52 @@
     -c, --config=FILENAME     : use configuration file FILENAME
 """
 
+def find_expired_objects(old_install_objects, new_install_objects):
+    """
+    Compared old_install_objects with new_install_objects to find which older
+    install objects are not needed/updated in the new install objects
+
+    old_install_objects: list of objects which are existing in the installation
+    new_install_objects: list of objects from the new installation
+    return: the expired objects
+    """
+
+    expired_objects = list()
+    old_install_objects.sort(key=(lambda f_object: f_object.name))
+    new_install_objects.sort(key=(lambda f_object: f_object.name))
+    old_obj_cnt = new_obj_cnt = 0
+    while True:
+        if old_obj_cnt == len(old_install_objects):
+            break               # Only exit condition
+        if old_install_objects[old_obj_cnt].hash == "-LINK":
+            expired_objects.append(old_install_objects[old_obj_cnt])
+            # Store the link mapping
+            old_obj_cnt += 1
+            continue
+        if new_obj_cnt == len(new_install_objects):
+            expired_objects.append(old_install_objects[old_obj_cnt])
+            old_obj_cnt += 1
+            continue
+        if (old_install_objects[old_obj_cnt].name
+            < new_install_objects[new_obj_cnt].name):
+            expired_objects.append(old_install_objects[old_obj_cnt])
+            old_obj_cnt += 1
+            continue
+        if (new_install_objects[new_obj_cnt].name
+            < old_install_objects[old_obj_cnt].name):
+            new_obj_cnt += 1
+            continue
+        if (old_install_objects[old_obj_cnt].name
+            = new_install_objects[new_obj_cnt].name):
+            # If the hash is not the same, we delete older object
+            if (old_install_objects[old_obj_cnt].hash 
+                != new_install_objects[new_obj_cnt].hash):
+                expired_objects.append(old_install_objects[old_obj_cnt])
+                old_obj_cnt += 1
+            else:
+                new_install_objects.pop(new_obj_cnt)
+    return expired_objects
+
 def main():
     """Execution start point."""
     external_config_file = None
@@ -80,88 +126,69 @@
     # We have to read the install manifest to know the currently installed
     # files. install_dir must point to an already installed location, if not
     # we'll fail
-    install_manifest = open(os.path.join(install_dir, 
-                                         
"share/gnunet-update/install-manifest"),
-                            "rb");
-    install_manifest_files = install_manifest.readlines()
-    install_manifest.close()
+    (old_install_objects,
+     old_install_deps) = install_manifest.read_from_file(install_dir)
 
-    previously_installed_depfiles = [ file for file in install_manifest_files
-                                  if file.startswith("lib/gnunet-deps") ]
+    # To be refreshed objects are the objects which are present in the older
+    # version and the newer version, however, in the newer version their hash
+    # is different which means they have new updated content
 
-    # We delete all the files except the installed dependencies
-    delete_list = [file for file in install_manifest_files
-                   if not in (previosly_installed_depfiles + ["lib"])]
+    new_install_objects = (metadata.binary_objects +
+                           metadata.other_objects)
+    to_be_deleted_objects = find_expired_objects(old_install_objects,
+                                                 new_install_objects)
 
-    # First delete the files
-    for file in delete_list:
-        if os.path.isdir(file):
-            continue            # We skip deleting directories
-        os.remove(file)
-        delete_list.remove(file)
-    # Now delete directories
-    for dir in delete_list:
-        os.rmdir(dir)
-    
-    # find the dependencies installed in the dep dir
-    regex = re.compile("(.+\.so\.\d+).*")
-    previously_installed_deps = list()
-    for dep_file in previously_installed_depfiles:
-        match = regex.match(os.path.basename(dep_file))
-        if match:
-            name = match.group(1)
-            dep = Dependency(name)
-            dep.set_path(dep_file)
-            previously_installed_deps.append(dep)
-        else:
-            raise Exception("Unable to determine the name of installed 
dependency")
-    
-    available_libs = util.get_available_libs()    # already available 
dependencies
-    needed_deps = metadata.dependencies.keys() # Required dependencies
-    satisfying_deps = list()                   # satisfying dependencies
-    to_be_installed_deps = util.filter_needed_deps(needed_deps,
-                                                   available_libs)
-    to_be_installed_deps = util.filter_needed_deps(to_be_installed_deps,
-                                                   previously_installed_deps,
-                                                   trace=satisfying_deps)
-    # No longer needed - to be deleted deps
-    old_notuseful_deps = [dep for dep in previously_installed_deps
-                          if dep not in satisfying_deps]
-    # Delete the dependencies which are no longer needed
-    for dep in old_notuseful_deps:
-        os.remove(dep.path)
+    # Delete objects in the to_be_deleted list
+    for f_object in to_be_deleted_objects:
+        if os.path.isdir(f_object): # delete files first
+            continue
+        os.remove(f_object)
+        to_be_deleted_objects.remove(f_object)
+    for f_object in to_be_deleted_objects: #Only directories should be 
remaining
+        os.rmdir(f_object)      # delete them
 
-    # Remove the symbolic links in the dep dir
-    for root, dirs, files in os.walk(os.path.join(install_dir,
-                                                  "lib/gnunet-deps")):
-        for file in files:
-            file_path = os.path.join(root, file)
-            if os.path.islink(file_path):
-                os.remove(file_path)
+    # Useful files retained from older installation
+    retained_objects = [ f_object for f_object in old_install_objects
+                         if f_object not in to_be_deleted_objects]
 
-    installed_files = list()    # List of files that are installed from package
-    # Extract the package's main software contents
-    util.extract_install_prefix(package_tarfile, install_dir, installed_files)
+    installed_files = list()
+    map(lambda f_object: installed_files.append(f_object), retained_objects)
     
-    ######## DUPLICATED FROM INSTALL ########
+    # Extract the files we need
+    util.extract_install_prefix(new_install_objects,
+                                package_tarfile,
+                                install_dir,
+                                installed_files)
 
-    # Install the needed dependencies from tarfile
+    # Dependency update and handling
+    needed_deps = metadata.dependencies.keys() # Required dependencies
+    expired_deps = find_expired_objects(old_install_deps,
+                                        needed_deps)
+    retained_deps = [dep for dep in old_install_deps
+                     if dep not in expired_deps]
+    needed_deps2 = filter_needed_deps(needed_deps,
+                                      retained_deps)
+    to_be_installed_deps = filter_needed_deps(needed_deps2,
+                                              util.get_available_libs())
+                                       
     dep_dir = os.path.join(install_dir, "lib/gnunet-deps")
-    if not os.path.exists(dep_dir):
-        os.makedirs(dep_dir)
-    
-    # Add the gnunet dependency dir to the install manifest
-    installed_files.append("lib/gnunet-deps")
     orig_working_dir = os.getcwd()
-    # Change to dep install dir
     os.chdir(dep_dir)
+    
+    # Delete the expired deps
+    for dep in expired_deps:
+        os.remove(dep.realname)
+        os.remove(dep.name)
 
+    install_dep_files = list()
+    map(lambda dep: instal_dep_files.append(dep), retained_deps)
+
+    # Install the needed dependencies from tarfile
     for dep in to_be_installed_deps:
         dep_tarinfo = package_tarfile.getmember("dependencies/" + dep.realname)
         # Remove the `dependencies/' in member.name
         dep_tarinfo.name = dep_tarinfo.name.replace("dependencies/","",1)
         package_tarfile.extract(dep_tarinfo, "./")
-        installed_files.append(os.path.join("lib/gnunet-deps/", 
dep_tarinfo.name))
         # Check the hash of the extracted file
         if util.sha512_hexdigest(dep_tarinfo.name) != dep.hash:
             print (dep_tarinfo.name + 
@@ -171,14 +198,14 @@
             package_tarfile.close()
             os.chdir(orig_working_dir)
             shutil.rmtree(install_dir)
-            sys.exit(0)
+            sys.exit(-1)
         
         # Generate symbolic link from dep.name to dep.realname
         # NOTE: Available only on Unix type systems!
-        if os.path.exists(dep.name):
-            os.remove(dep.name)
         os.symlink(dep.realname, dep.name)
-        installed_files.append(os.path.join("lib/gnunet-deps", dep.name))
+        installed_dep_files.append(DependencyFileObject(dep.name,
+                                                        path=None,
+                                                        hash=dep.hash))
     package_tarfile.close()
 
     # run ldconfig -n in the dep_dir
@@ -187,15 +214,9 @@
     os.chdir(orig_working_dir)
 
     # Write install manifest file
-    if not os.path.exists(os.path.join(install_dir, "share/gnunet-update/")):
-        os.makedirs(os.path.join(install_dir, "share/gnunet-update/"))
-    install_manifest_fd = open(os.path.join(install_dir,
-                                            
"share/gnunet-update/install-manifest"),
-                               "wb") 
-    map((lambda name: install_manifest_fd.write(name + '\n')), installed_files)
-    install_manifest_fd.close()
-    ######## DUPLICATED FROM INSTALL ########
-    # FIXME: Add shared library installation message
+    install_manifest.write_to_file(install_dir, 
+                                   installed_files,
+                                   installed_dep_files)
     
 if "__main__" == __name__:
     main()

Modified: gnunet-update/gnunet_update/util.py
===================================================================
--- gnunet-update/gnunet_update/util.py 2011-12-11 15:39:53 UTC (rev 18556)
+++ gnunet-update/gnunet_update/util.py 2011-12-12 10:06:19 UTC (rev 18557)
@@ -300,4 +300,4 @@
             print "Malicious code detected. Stopping installation"
             print member_obj.name + "<-->" + member_obj.hash
             sys.exit(-1)
-        if installed_files is not None: installed_files.append(member.name)
+        if installed_files is not None: installed_files.append(member_obj)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]