home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / DistUpgrade / DistUpgradeAufs.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-10-12  |  7.7 KB  |  244 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import string
  5. import logging
  6. import os
  7. import os.path as os
  8. import subprocess
  9. import tempfile
  10. systemdirs = [
  11.     '/bin',
  12.     '/boot',
  13.     '/etc',
  14.     '/initrd',
  15.     '/lib',
  16.     '/lib32',
  17.     '/sbin',
  18.     '/usr',
  19.     '/var']
  20.  
  21. def aufsOptionsAndEnvironmentSetup(options, config):
  22.     ''' setup the environment based on the config and options
  23.     It will use
  24.     config("Aufs","Enabled") - to show if its enabled
  25.     and
  26.     config("Aufs","RWDir") - for the writable overlay dir
  27.     '''
  28.     logging.debug('aufsOptionsAndEnvironmentSetup()')
  29.     if options and options.useAufs:
  30.         logging.debug('enabling full overlay from commandline')
  31.         config.set('Aufs', 'Enabled', True)
  32.         config.set('Aufs', 'EnableFullOverlay', True)
  33.     
  34.     tmprw = tempfile.mkdtemp(prefix = 'upgrade-rw-')
  35.     aufs_rw_dir = config.getWithDefault('Aufs', 'RWDir', tmprw)
  36.     logging.debug("using '%s' as aufs_rw_dir" % aufs_rw_dir)
  37.     os.environ['RELEASE_UPGRADE_AUFS_RWDIR'] = aufs_rw_dir
  38.     config.set('Aufs', 'RWDir', aufs_rw_dir)
  39.     tmpchroot = tempfile.mkdtemp(prefix = 'upgrade-chroot-')
  40.     os.chmod(tmpchroot, 493)
  41.     aufs_chroot_dir = config.getWithDefault('Aufs', 'ChrootDir', tmpchroot)
  42.     logging.debug("using '%s' as aufs chroot dir" % aufs_chroot_dir)
  43.     if config.getWithDefault('Aufs', 'EnableFullOverlay', False):
  44.         logging.debug('enabling aufs full overlay (from config)')
  45.         config.set('Aufs', 'Enabled', True)
  46.         os.environ['RELEASE_UPGRADE_USE_AUFS_FULL_OVERLAY'] = '1'
  47.     
  48.     if config.getWithDefault('Aufs', 'EnableChrootOverlay', False):
  49.         logging.debug('enabling aufs chroot overlay')
  50.         config.set('Aufs', 'Enabled', True)
  51.         os.environ['RELEASE_UPGRADE_USE_AUFS_CHROOT'] = aufs_chroot_dir
  52.     
  53.     if config.getWithDefault('Aufs', 'EnableChrootRsync', False):
  54.         logging.debug('enable aufs chroot rsync back to real system')
  55.         os.environ['RELEASE_UPGRADE_RSYNC_AUFS_CHROOT'] = '1'
  56.     
  57.  
  58.  
  59. def _bindMount(from_dir, to_dir, rbind = False):
  60.     ''' helper that bind mounts a given dir to a new place '''
  61.     if not os.path.exists(to_dir):
  62.         os.makedirs(to_dir)
  63.     
  64.     if rbind:
  65.         bind = '--rbind'
  66.     else:
  67.         bind = '--bind'
  68.     cmd = [
  69.         'mount',
  70.         bind,
  71.         from_dir,
  72.         to_dir]
  73.     logging.debug('cmd: %s' % cmd)
  74.     res = subprocess.call(cmd)
  75.     if res != 0:
  76.         logging.error("Failed to bind mount from '%s' to '%s'" % (from_dir, to_dir))
  77.         return False
  78.     return True
  79.  
  80.  
  81. def _aufsOverlayMount(target, rw_dir, chroot_dir = '/'):
  82.     ''' 
  83.     helper that takes a target dir and mounts a rw dir over it, e.g.
  84.     /var , /tmp/upgrade-rw
  85.     '''
  86.     if not os.path.exists(rw_dir + target):
  87.         os.makedirs(rw_dir + target)
  88.     
  89.     if not os.path.exists(chroot_dir + target):
  90.         os.makedirs(chroot_dir + target)
  91.     
  92.     cmd = [
  93.         'mount',
  94.         '-t',
  95.         'aufs',
  96.         '-o',
  97.         'br:%s:%s=ro' % (rw_dir + target, target),
  98.         'none',
  99.         chroot_dir + target]
  100.     res = subprocess.call(cmd)
  101.     if res != 0:
  102.         logging.error("Failed to mount rw aufs overlay for '%s'" % target)
  103.         return False
  104.     logging.debug("cmd '%s' return '%s' " % (cmd, res))
  105.     return True
  106.  
  107.  
  108. def is_aufs_mount(dir):
  109.     ''' test if the given dir is already mounted with aufs overlay '''
  110.     for line in open('/proc/mounts'):
  111.         (device, mountpoint, fstype, options, a, b) = line.split()
  112.         if device == 'none' and fstype == 'aufs' and mountpoint == dir:
  113.             return True
  114.     
  115.     return False
  116.  
  117.  
  118. def is_submount(mountpoint, systemdirs):
  119.     ''' helper: check if the given mountpoint is a submount of a systemdir '''
  120.     logging.debug('is_submount: %s %s' % (mountpoint, systemdirs))
  121.     for d in systemdirs:
  122.         if not d.endswith('/'):
  123.             d += '/'
  124.         
  125.         if mountpoint.startswith(d):
  126.             return True
  127.     
  128.     return False
  129.  
  130.  
  131. def is_real_fs(fs):
  132.     if fs.startswith('fuse'):
  133.         return False
  134.     if fs in ('rootfs', 'tmpfs', 'proc', 'fusectrl', 'aufs', 'devpts', 'binfmt_misc', 'sysfs'):
  135.         return False
  136.     return True
  137.  
  138.  
  139. def doAufsChrootRsync(aufs_chroot_dir):
  140.     '''
  141.     helper that rsyncs the changes in the aufs chroot back to the
  142.     real system
  143.     '''
  144.     for d in systemdirs:
  145.         if not os.path.exists(d):
  146.             continue
  147.         
  148.         cmd = [
  149.             'rsync',
  150.             '-aHAX',
  151.             '--del',
  152.             '-v',
  153.             '--progress',
  154.             '/%s/%s/' % (aufs_chroot_dir, d),
  155.             '/%s/' % d]
  156.         logging.debug("running: '%s'" % cmd)
  157.         ret = subprocess.call(cmd)
  158.         logging.debug('rsync back result for %s: %i' % (d, ret))
  159.     
  160.     return True
  161.  
  162.  
  163. def doAufsChroot(aufs_rw_dir, aufs_chroot_dir):
  164.     ''' helper that sets the chroot up and does chroot() into it '''
  165.     if not setupAufsChroot(aufs_rw_dir, aufs_chroot_dir):
  166.         return False
  167.     os.chroot(aufs_chroot_dir)
  168.     os.chdir('/')
  169.     return True
  170.  
  171.  
  172. def setupAufsChroot(rw_dir, chroot_dir):
  173.     ''' setup aufs chroot that is based on / but with a writable overlay '''
  174.     mounts = open('/proc/mounts').read()
  175.     for d in os.listdir('/'):
  176.         d = os.path.join('/', d)
  177.         if os.path.isdir(d):
  178.             if d in systemdirs:
  179.                 logging.debug('bind mounting %s' % d)
  180.                 if not _aufsOverlayMount(d, rw_dir, chroot_dir):
  181.                     return False
  182.             else:
  183.                 logging.debug('overlay mounting %s' % d)
  184.                 if not _bindMount(d, chroot_dir + d, rbind = True):
  185.                     return False
  186.         d in systemdirs
  187.     
  188.     needs_bind_mount = set()
  189.     for line in map(string.strip, mounts.split('\n')):
  190.         if not line:
  191.             continue
  192.         
  193.         (device, mountpoint, fstype, options, a, b) = line.split()
  194.         if fstype != 'aufs' and not is_real_fs(fstype) and is_submount(mountpoint, systemdirs):
  195.             logging.debug('found %s that needs bind mount', mountpoint)
  196.             if not _bindMount(mountpoint, chroot_dir + mountpoint):
  197.                 return False
  198.             continue
  199.         _bindMount(mountpoint, chroot_dir + mountpoint)
  200.     
  201.     return True
  202.  
  203.  
  204. def setupAufs(rw_dir):
  205.     ''' setup aufs overlay over the rootfs '''
  206.     logging.debug('setupAufs')
  207.     if not os.path.exists('/proc/mounts'):
  208.         logging.debug('no /proc/mounts, can not do aufs overlay')
  209.         return False
  210.     needs_bind_mount = set()
  211.     needs_bind_mount.add('/var/cache/apt/archives')
  212.     for line in open('/proc/mounts'):
  213.         (device, mountpoint, fstype, options, a, b) = line.split()
  214.         if is_real_fs(fstype) and is_submount(mountpoint, systemdirs):
  215.             logging.warning('mountpoint %s submount of systemdir' % mountpoint)
  216.             return False
  217.         if fstype != 'aufs' and not is_real_fs(fstype) and is_submount(mountpoint, systemdirs):
  218.             logging.debug('found %s that needs bind mount', mountpoint)
  219.             needs_bind_mount.add(mountpoint)
  220.             continue
  221.         is_submount(mountpoint, systemdirs)
  222.     
  223.     for d in needs_bind_mount:
  224.         if not _bindMount(d, rw_dir + '/needs_bind_mount/' + d):
  225.             return False
  226.     
  227.     for d in systemdirs:
  228.         if not is_aufs_mount(d):
  229.             if not _aufsOverlayMount(d, rw_dir):
  230.                 return False
  231.             continue
  232.         _aufsOverlayMount(d, rw_dir)
  233.     
  234.     for d in needs_bind_mount:
  235.         if not _bindMount(rw_dir + '/needs_bind_mount/' + d, d):
  236.             return False
  237.     
  238.     return True
  239.  
  240. if __name__ == '__main__':
  241.     logging.basicConfig(level = logging.DEBUG)
  242.     print setupAufsChroot('/tmp/upgrade-chroot-rw', '/tmp/upgrade-chroot')
  243.  
  244.