[elbe-devel] [PATCH 1/2] Add files protection from ChRootFilesystem's excursion.

dion at linutronix.de dion at linutronix.de
Fri Jul 19 12:06:57 CEST 2019


From: Olivier Dion <dion at linutronix.de>

If we modify one of the excursion's files, this modification won't be
commited since after exiting the context manager of the filesystem,
the excursion is undo.

Thus, the method ChRootFilsystem.protect takes a list of files to
protect from the excursion and return the filesytem object.  This can
be use in conjonction with the 'with' statement, allowing modification
of the protected files.

* Example

  Here the user wants to link "/etc/resolv.conf" to a target.  But
  "/etc/resolv.conf" is usually restored by the excursion.

  Using the new 'protect' method, we can bypass the excursion.

  ``````````````````````````````````````````````````````````````````````
  my_file = "/etc/resolv.conf"
  with rfs.protect({my_file}):
     link(my_file, to_some_target)
  ``````````````````````````````````````````````````````````````````````

Signed-off-by: Olivier Dion <dion at linutronix.de>
---
 elbepack/efilesystem.py | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/elbepack/efilesystem.py b/elbepack/efilesystem.py
index 8d766e3c..abfb239b 100644
--- a/elbepack/efilesystem.py
+++ b/elbepack/efilesystem.py
@@ -191,7 +191,10 @@ class Excursion(object):
     def end(cls, rfs):
         r = cls.RFS[rfs.path]
         for tmp in r:
-            tmp._undo_excursion(rfs)
+            if tmp.origin not in rfs.protect_from_excursion:
+                tmp._undo_excursion(rfs)
+            else:
+                tmp._del_rfs_file(tmp._saved_to(), rfs)
         del r
 
     def __init__(self, path, restore, dst):
@@ -199,10 +202,12 @@ class Excursion(object):
         self.restore = restore
         self.dst = dst
 
+    def _saved_to(self):
+        return "%s.orig" % self.origin
 
     def _do_excursion(self, rfs):
         if rfs.lexists(self.origin) and self.restore is True:
-            save_to = "%s.orig" % self.origin
+            save_to = self._saved_to()
             system('mv %s %s' % (rfs.fname(self.origin), rfs.fname(save_to)))
         if os.path.exists(self.origin):
             if self.dst is not None:
@@ -211,13 +216,17 @@ class Excursion(object):
                 dst = self.origin
             system('cp %s %s' % (self.origin, rfs.fname(dst)))
 
-    def _undo_excursion(self, rfs):
-        saved_to = "%s.orig" % self.origin
-        if rfs.lexists(self.origin):
+    # This should be a method of rfs
+    def _del_rfs_file(self, filename, rfs):
+        if rfs.lexists(filename):
             flags = "-f"
-            if rfs.isdir(self.origin):
+            if rfs.isdir(filename):
                 flags += "r"
-            system('rm %s %s' % (flags, rfs.fname(self.origin)))
+            system("rm %s %s" % (flags, rfs.fname(filename)))
+
+    def _undo_excursion(self, rfs):
+        saved_to = self._saved_to()
+        self._del_rfs_file(self.origin, rfs)
         if self.restore is True and rfs.lexists(saved_to):
             system('mv %s %s' % (rfs.fname(saved_to), rfs.fname(self.origin)))
 
@@ -229,6 +238,7 @@ class ChRootFilesystem(ElbeFilesystem):
         self.interpreter = interpreter
         self.cwd = os.open("/", os.O_RDONLY)
         self.inchroot = False
+        self.protect_from_excursion = set()
 
     def __del__(self):
         os.close(self.cwd)
@@ -264,6 +274,11 @@ class ChRootFilesystem(ElbeFilesystem):
         self.umount()
 
         Excursion.end(self)
+        self.protect_from_excursion = set()
+
+    def protect(self, files):
+        self.protect_from_excursion = files
+        return self
 
     def mount(self):
         if self.path == '/':
-- 
2.11.0




More information about the elbe-devel mailing list