[elbe-devel] [PATCH v2 3/8] Add save excursion in ChRootFilesystem context

Torben Hohn torben.hohn at linutronix.de
Wed May 29 13:01:24 CEST 2019


On Tue, May 28, 2019 at 12:06:01PM +0200, dion at linutronix.de wrote:
> From: Olivier Dion <dion at linutronix.de>
> 
> Instead of manually copying/moving/deleting files around,
> the '__enter__' method of 'ChRootFilesystem' should save the
> excursion into 'self.excursion'.
> 
> The excursion can be hardcoded directly at the top of the
> '__enter__' method.  Depending on the filesystem object,
> other files can be add to the excursion as well dynamically.
> 
> To put a file into the excursion, 2 variables must be
> provide and 1 optional.
> 
> * 'path' - file on the *host* to copy to the RFS.
> * 'restore' - if to restore 'path' in the RFS on '__exit__'
> * 'dst' (optional) - Copy 'path' to 'dst'
> 
> If 'dst' is not provided, then 'path' is copy to the same
> place in the RFS.
> 
> Uppon exiting the 'ChrootFilesystem' context with '__exit__'
> the excursion is restored according to the policies in it.
> Finally, the excursion is deleted so it's reset in the next
> context.
> 
> Examples
> ========
> 
> ````````````````````````````````````````````````````````````
> Excursion.add(self, "/usr/bin")
> ````````````````````````````````````````````````````````````
> 
> On '__enter__'
> 
> * Move "/rfs/usr/bin" to "/rfs/usr/bin.orig", even if it's a
>   broken link
> 
> * Copy "/usr/bin" to "/rfs/usr/bin"
> 
> On '__exit__'
> 
> * Remove "/rfs/usr/bin"
> 
> * Move "/rfs/usr/bin.orig" to "/rfs/usr/bin"
> 
> ````````````````````````````````````````````````````````````
> ui = "/usr/share/elbe/qemu-elbe/elbe"
> Excursion.add(self, ui, False, "/usr/bin")
> ````````````````````````````````````````````````````````````
> 
> On '__enter__'
> 
> * Move "/usr/share/elbe/qemu-elbe/elbe" to "/rfs/usr/bin/elbe"
> 
> On '__exit__'
> 
> * Remove "/rfs/usr/bin/elbe"
> 
> Signed-off-by: Olivier Dion <dion at linutronix.de>

Reviewed-by: Torben Hohn <torben.hohn at linutronix.de>

> ---
>  elbepack/efilesystem.py | 99 ++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 65 insertions(+), 34 deletions(-)
> 
> diff --git a/elbepack/efilesystem.py b/elbepack/efilesystem.py
> index 1f6428e0..9181c89d 100644
> --- a/elbepack/efilesystem.py
> +++ b/elbepack/efilesystem.py
> @@ -167,8 +167,61 @@ class ElbeFilesystem(Filesystem):
>          if xml_fname is not None:
>              licence_xml.write(xml_fname)
>  
> +class Excursion(object):
> +
> +    RFS = {}
> +
> +    @classmethod
> +    def begin(cls, rfs):
> +        cls.RFS[rfs.path] = []
> +
> +    @classmethod
> +    def add(cls, rfs, path, restore=True, dst=None):
> +        cls.RFS[rfs.path].append(Excursion(path, restore, dst))
> +
> +    @classmethod
> +    def do(cls, rfs):
> +        r = cls.RFS[rfs.path]
> +        for tmp in r:
> +            tmp._do_excursion(rfs)
> +
> +    @classmethod
> +    def end(cls, rfs):
> +        r = cls.RFS[rfs.path]
> +        for tmp in r:
> +            tmp._undo_excursion(rfs)
> +        del r
> +
> +    def __init__(self, path, restore, dst):
> +        self.origin = path
> +        self.restore = restore
> +        self.dst = dst
> +
> +
> +    def _do_excursion(self, rfs):
> +        if rfs.lexists(self.origin) and self.restore is True:
> +            save_to = "%s.orig" % self.origin
> +            os.system('mv %s %s' % (rfs.fname(self.origin), rfs.fname(save_to)))
> +        if os.path.exists(self.origin):
> +            if self.dst is not None:
> +                dst = self.dst
> +            else:
> +                dst = self.origin
> +            os.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):
> +            flags = "-f"
> +            if rfs.isdir(self.origin):
> +                flags += "r"
> +            os.system('rm %s %s' % (flags, rfs.fname(self.origin)))
> +        if self.restore is True and rfs.lexists(saved_to):
> +            os.system('mv %s %s' % (rfs.fname(saved_to), rfs.fname(self.origin)))
> +
>  
>  class ChRootFilesystem(ElbeFilesystem):
> +
>      def __init__(self, path, interpreter=None, clean=False):
>          ElbeFilesystem.__init__(self, path, clean)
>          self.interpreter = interpreter
> @@ -179,32 +232,27 @@ class ChRootFilesystem(ElbeFilesystem):
>          os.close(self.cwd)
>  
>      def __enter__(self):
> +        Excursion.begin(self)
> +        Excursion.add(self, "/etc/resolv.conf")
> +        Excursion.add(self, "/etc/apt/apt.conf")
> +        Excursion.add(self, "/usr/sbin/policy-rc.d")
> +
>          if self.interpreter:
>              if not self.exists("usr/bin"):
> -                self.mkdir("usr/bin")
> +                if self.islink("usr/bin"):
> +                    Excursion.add(self, "/usr/bin")
>  
>              ui = "/usr/share/elbe/qemu-elbe/" + self.interpreter
>              if not os.path.exists(ui):
>                  ui = "/usr/bin/" + self.interpreter
> -            os.system('cp %s %s' % (ui, self.fname("usr/bin")))
>  
> -        if self.exists("/etc/resolv.conf"):
> -            os.system('mv %s %s' % (self.fname("etc/resolv.conf"),
> -                                    self.fname("etc/resolv.conf.orig")))
> -        os.system('cp %s %s' % ("/etc/resolv.conf",
> -                                self.fname("etc/resolv.conf")))
> +            Excursion.add(self, ui, False, "/usr/bin")
>  
> -        if self.exists("/etc/apt/apt.conf"):
> -            os.system('cp %s %s' % (self.fname("/etc/apt/apt.conf"),
> -                                    self.fname("/etc/apt/apt.conf.orig")))
> -        if os.path.exists("/etc/apt/apt.conf"):
> -            os.system('cp %s %s' % ("/etc/apt/apt.conf",
> -                                    self.fname("/etc/apt/")))
> +        Excursion.do(self)
>  
> +        self.mkdir_p("usr/bin")
>          self.mkdir_p("usr/sbin")
> -        self.write_file("usr/sbin/policy-rc.d",
> -                        0o755, "#!/bin/sh\nexit 101\n")
> -
> +        self.write_file("usr/sbin/policy-rc.d", 0o755, "#!/bin/sh\nexit 101\n")
>          self.mount()
>          return self
>  
> @@ -212,25 +260,8 @@ class ChRootFilesystem(ElbeFilesystem):
>          if self.inchroot:
>              self.leave_chroot()
>          self.umount()
> -        if self.interpreter:
> -            os.system('rm -f %s' %
> -                      os.path.join(self.path, "usr/bin/" + self.interpreter))
> -
> -        os.system('rm -f %s' % (self.fname("etc/resolv.conf")))
> -
> -        if self.exists("/etc/resolv.conf.orig"):
> -            os.system('mv %s %s' % (self.fname("etc/resolv.conf.orig"),
> -                                    self.fname("etc/resolv.conf")))
> -
> -        if self.exists("/etc/apt/apt.conf"):
> -            os.system('rm -f %s' % (self.fname("etc/apt/apt.conf")))
> -
> -        if self.exists("/etc/apt/apt.conf.orig"):
> -            os.system('mv %s %s' % (self.fname("etc/apt/apt.conf.orig"),
> -                                    self.fname("etc/apt/apt.conf")))
>  
> -        if self.exists("/usr/sbin/policy-rc.d"):
> -            os.system('rm -f %s' % (self.fname("usr/sbin/policy-rc.d")))
> +        Excursion.end(self)
>  
>      def mount(self):
>          if self.path == '/':
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> elbe-devel mailing list
> elbe-devel at linutronix.de
> https://lists.linutronix.de/mailman/listinfo/elbe-devel

-- 
Torben Hohn
Linutronix GmbH | Bahnhofstrasse 3 | D-88690 Uhldingen-Mühlhofen
Phone: +49 7556 25 999 18; Fax.: +49 7556 25 999 99

Hinweise zum Datenschutz finden Sie hier (Informations on data privacy 
can be found here): https://linutronix.de/kontakt/Datenschutz.php

Linutronix GmbH | Firmensitz (Registered Office): Uhldingen-Mühlhofen | 
Registergericht (Registration Court): Amtsgericht Freiburg i.Br., HRB700 
806 | Geschäftsführer (Managing Directors): Heinz Egger, Thomas Gleixner



More information about the elbe-devel mailing list