home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- import string
- import logging
- import os
- import os.path as os
- import subprocess
- import tempfile
- systemdirs = [
- '/bin',
- '/boot',
- '/etc',
- '/initrd',
- '/lib',
- '/lib32',
- '/sbin',
- '/usr',
- '/var']
-
- def aufsOptionsAndEnvironmentSetup(options, config):
- ''' setup the environment based on the config and options
- It will use
- config("Aufs","Enabled") - to show if its enabled
- and
- config("Aufs","RWDir") - for the writable overlay dir
- '''
- logging.debug('aufsOptionsAndEnvironmentSetup()')
- if options and options.useAufs:
- logging.debug('enabling full overlay from commandline')
- config.set('Aufs', 'Enabled', True)
- config.set('Aufs', 'EnableFullOverlay', True)
-
- tmprw = tempfile.mkdtemp(prefix = 'upgrade-rw-')
- aufs_rw_dir = config.getWithDefault('Aufs', 'RWDir', tmprw)
- logging.debug("using '%s' as aufs_rw_dir" % aufs_rw_dir)
- os.environ['RELEASE_UPGRADE_AUFS_RWDIR'] = aufs_rw_dir
- config.set('Aufs', 'RWDir', aufs_rw_dir)
- tmpchroot = tempfile.mkdtemp(prefix = 'upgrade-chroot-')
- os.chmod(tmpchroot, 493)
- aufs_chroot_dir = config.getWithDefault('Aufs', 'ChrootDir', tmpchroot)
- logging.debug("using '%s' as aufs chroot dir" % aufs_chroot_dir)
- if config.getWithDefault('Aufs', 'EnableFullOverlay', False):
- logging.debug('enabling aufs full overlay (from config)')
- config.set('Aufs', 'Enabled', True)
- os.environ['RELEASE_UPGRADE_USE_AUFS_FULL_OVERLAY'] = '1'
-
- if config.getWithDefault('Aufs', 'EnableChrootOverlay', False):
- logging.debug('enabling aufs chroot overlay')
- config.set('Aufs', 'Enabled', True)
- os.environ['RELEASE_UPGRADE_USE_AUFS_CHROOT'] = aufs_chroot_dir
-
- if config.getWithDefault('Aufs', 'EnableChrootRsync', False):
- logging.debug('enable aufs chroot rsync back to real system')
- os.environ['RELEASE_UPGRADE_RSYNC_AUFS_CHROOT'] = '1'
-
-
-
- def _bindMount(from_dir, to_dir, rbind = False):
- ''' helper that bind mounts a given dir to a new place '''
- if not os.path.exists(to_dir):
- os.makedirs(to_dir)
-
- if rbind:
- bind = '--rbind'
- else:
- bind = '--bind'
- cmd = [
- 'mount',
- bind,
- from_dir,
- to_dir]
- logging.debug('cmd: %s' % cmd)
- res = subprocess.call(cmd)
- if res != 0:
- logging.error("Failed to bind mount from '%s' to '%s'" % (from_dir, to_dir))
- return False
- return True
-
-
- def _aufsOverlayMount(target, rw_dir, chroot_dir = '/'):
- '''
- helper that takes a target dir and mounts a rw dir over it, e.g.
- /var , /tmp/upgrade-rw
- '''
- if not os.path.exists(rw_dir + target):
- os.makedirs(rw_dir + target)
-
- if not os.path.exists(chroot_dir + target):
- os.makedirs(chroot_dir + target)
-
- cmd = [
- 'mount',
- '-t',
- 'aufs',
- '-o',
- 'br:%s:%s=ro' % (rw_dir + target, target),
- 'none',
- chroot_dir + target]
- res = subprocess.call(cmd)
- if res != 0:
- logging.error("Failed to mount rw aufs overlay for '%s'" % target)
- return False
- logging.debug("cmd '%s' return '%s' " % (cmd, res))
- return True
-
-
- def is_aufs_mount(dir):
- ''' test if the given dir is already mounted with aufs overlay '''
- for line in open('/proc/mounts'):
- (device, mountpoint, fstype, options, a, b) = line.split()
- if device == 'none' and fstype == 'aufs' and mountpoint == dir:
- return True
-
- return False
-
-
- def is_submount(mountpoint, systemdirs):
- ''' helper: check if the given mountpoint is a submount of a systemdir '''
- logging.debug('is_submount: %s %s' % (mountpoint, systemdirs))
- for d in systemdirs:
- if not d.endswith('/'):
- d += '/'
-
- if mountpoint.startswith(d):
- return True
-
- return False
-
-
- def is_real_fs(fs):
- if fs.startswith('fuse'):
- return False
- if fs in ('rootfs', 'tmpfs', 'proc', 'fusectrl', 'aufs', 'devpts', 'binfmt_misc', 'sysfs'):
- return False
- return True
-
-
- def doAufsChrootRsync(aufs_chroot_dir):
- '''
- helper that rsyncs the changes in the aufs chroot back to the
- real system
- '''
- for d in systemdirs:
- if not os.path.exists(d):
- continue
-
- cmd = [
- 'rsync',
- '-aHAX',
- '--del',
- '-v',
- '--progress',
- '/%s/%s/' % (aufs_chroot_dir, d),
- '/%s/' % d]
- logging.debug("running: '%s'" % cmd)
- ret = subprocess.call(cmd)
- logging.debug('rsync back result for %s: %i' % (d, ret))
-
- return True
-
-
- def doAufsChroot(aufs_rw_dir, aufs_chroot_dir):
- ''' helper that sets the chroot up and does chroot() into it '''
- if not setupAufsChroot(aufs_rw_dir, aufs_chroot_dir):
- return False
- os.chroot(aufs_chroot_dir)
- os.chdir('/')
- return True
-
-
- def setupAufsChroot(rw_dir, chroot_dir):
- ''' setup aufs chroot that is based on / but with a writable overlay '''
- mounts = open('/proc/mounts').read()
- for d in os.listdir('/'):
- d = os.path.join('/', d)
- if os.path.isdir(d):
- if d in systemdirs:
- logging.debug('bind mounting %s' % d)
- if not _aufsOverlayMount(d, rw_dir, chroot_dir):
- return False
- else:
- logging.debug('overlay mounting %s' % d)
- if not _bindMount(d, chroot_dir + d, rbind = True):
- return False
- d in systemdirs
-
- needs_bind_mount = set()
- for line in map(string.strip, mounts.split('\n')):
- if not line:
- continue
-
- (device, mountpoint, fstype, options, a, b) = line.split()
- if fstype != 'aufs' and not is_real_fs(fstype) and is_submount(mountpoint, systemdirs):
- logging.debug('found %s that needs bind mount', mountpoint)
- if not _bindMount(mountpoint, chroot_dir + mountpoint):
- return False
- continue
- _bindMount(mountpoint, chroot_dir + mountpoint)
-
- return True
-
-
- def setupAufs(rw_dir):
- ''' setup aufs overlay over the rootfs '''
- logging.debug('setupAufs')
- if not os.path.exists('/proc/mounts'):
- logging.debug('no /proc/mounts, can not do aufs overlay')
- return False
- needs_bind_mount = set()
- needs_bind_mount.add('/var/cache/apt/archives')
- for line in open('/proc/mounts'):
- (device, mountpoint, fstype, options, a, b) = line.split()
- if is_real_fs(fstype) and is_submount(mountpoint, systemdirs):
- logging.warning('mountpoint %s submount of systemdir' % mountpoint)
- return False
- if fstype != 'aufs' and not is_real_fs(fstype) and is_submount(mountpoint, systemdirs):
- logging.debug('found %s that needs bind mount', mountpoint)
- needs_bind_mount.add(mountpoint)
- continue
- is_submount(mountpoint, systemdirs)
-
- for d in needs_bind_mount:
- if not _bindMount(d, rw_dir + '/needs_bind_mount/' + d):
- return False
-
- for d in systemdirs:
- if not is_aufs_mount(d):
- if not _aufsOverlayMount(d, rw_dir):
- return False
- continue
- _aufsOverlayMount(d, rw_dir)
-
- for d in needs_bind_mount:
- if not _bindMount(rw_dir + '/needs_bind_mount/' + d, d):
- return False
-
- return True
-
- if __name__ == '__main__':
- logging.basicConfig(level = logging.DEBUG)
- print setupAufsChroot('/tmp/upgrade-chroot-rw', '/tmp/upgrade-chroot')
-
-