def configure_hardware(self): """reconfiguring several packages which depends on the hardware system in which has been installed on and need some automatic configurations to get work.""" self.chrex('mount', '-t', 'proc', 'proc', '/proc') self.chrex('mount', '-t', 'sysfs', 'sysfs', '/sys') # Active the swap partition for the initramfs well configuring for device, path in self.mountpoints.items(): if path == 'swap' and device.startswith('/dev/'): initramfs = open('/etc/mkinitramfs/initramfs.conf').read() new = initramfs.replace("#RESUME=","RESUME=%s" % device) file = open(os.path.join(self.target, 'etc/mkinitramfs/initramfs.conf') ,'w') file.write(new) file.close() misc.ex('cp', '/etc/X11/xorg.conf', os.path.join(self.target, 'etc/X11/xorg.conf') ) packages = ['gnome-panel', 'gnome-panel-data', 'ssh', 'linux-image-' + self.kernel_version] try: for package in packages: self.copy_debconf(package) self.reconfigure(package) finally: self.chrex('umount', '/proc') self.chrex('umount', '/sys') return True
def umount_source(self): """umounting loop system from cloop or squashfs system.""" if not misc.ex('umount', self.source): return False if self.unionfs: return True if ( not misc.ex('losetup', '-d', self.dev) and self.dev != '' ): return False return True
def configure_bootloader(self): # Copying the old boot config files = ['/etc/lilo.conf', '/boot/grub/menu.lst','/etc/grub.conf', '/boot/grub/grub.conf'] TEST = '/mnt/test/' target_dev = self.mountpoints['/'] grub_dev = misc.grub_dev(target_dev) distro = self.distro.capitalize() proc_file = open('/proc/partitions').readlines() parts = [] for entry in proc_file[2:]: dev = entry.split() if len(dev[3]) == 4: parts.append(dev[3]) misc.ex('mkdir', TEST) for part in parts: if misc.ex('mount', '/dev/' + part , TEST): for file in files: if os.path.exists(TEST + file): misc.ex('cp', TEST + file, self.target + file) misc.ex('umount', TEST) # The new boot self.chex('/usr/sbin/mkinitrd') # For the Grub grub_conf = open(self.target + '/boot/grub/menu.lst', 'a') grub_conf.write(' \ e %s \ (%s) \ el (%s)/vmlinuz-%s root=%s ro vga=791 quiet \ rd (%s)/initrd.img-%s \ default ' % \ (distro, grub_dev, grub_dev, self.kernel_version, target_dev, grub_dev, self.kernel_version) ) grub_conf.close() # For the Yaboot if not os.path.exists(self.target + '/etc/yaboot.conf'): misc.make_yaboot_header(self.target, target_dev) yaboot_conf = open(self.target + '/etc/yaboot.conf', 'a') yaboot_conf.write(' \ default=%s \ \ image=/boot/vmlinux-%s \ label=%s \ read-only \ initrd=/boot/initrd.img-%s \ append="quiet splash" \ ' % (distro, self.kernel_version, distro, self.kernel_version) ) yaboot_conf.close() misc.ex('/usr/share/setup-tool-backends/scripts/boot-conf','--get', '>',self.target + '/tmp/boot.xml') self.chex('/usr/share/setup-tool-backends/scripts/boot-conf','--set', '<','/tmp/boot.xml')
def mount_target(self): if not os.path.isdir(self.target): os.mkdir(self.target) misc.ex('mount', self.mountpoints['/'], self.target) for path, device in self.mountpoints.items(): if path in ('/', 'swap'): continue path = os.path.join(self.target, path[1:]) os.mkdir(path) if not misc.ex('mount', device, path): return False return True
def mount_target(self): if not os.path.isdir(self.target): os.mkdir(self.target) misc.ex("mount", self.mountpoints["/"], self.target) for path, device in self.mountpoints.items(): if path in ("/", "swap"): continue path = os.path.join(self.target, path[1:]) os.mkdir(path) if not misc.ex("mount", device, path): return False return True
def part_scheme(drive, scheme): if scheme.has_key('extended'): misc.ex("parted -s %s mkpart extended %d %d" % (drive, scheme['extended'][0], scheme['extended'][1]) ) misc.ex("parted -s %s mkpart logical ext2 %d %d" % (drive, scheme['root'][0], scheme['root'][1]) ) misc.ex("parted -s %s mkpart logical ext2 %d %d" % (drive, scheme['home'][0], scheme['home'][1]) ) misc.ex("parted -s %s mkpart logical linux-swap %d %d" % (drive, scheme['swap'][0], scheme['swap'][1]) ) # TODO: Some error code handling needed with the execution of this commands # above return True
def umount_target(self): """umounting selected partitions.""" ordered_list = [] for device, path in self.mountpoints.items(): if path in ('swap',): continue path = os.path.join(self.target, path[1:]) ordered_list.append((len(path), device, path)) ordered_list.reverse() for length, device, path in ordered_list: try: misc.ex('umount', '-f', os.path.join(self.target, path)) except Exception, e: print e
def mount_source(self): from os import path files = ['/cdrom/casper/filesystem.cloop', '/cdrom/META/META.squashfs'] for f in files: if path.isfile(f) and path.splitext(f)[1] == '.cloop': file = f self.dev = '/dev/cloop1' elif path.isfile(f) and path.splitext(f)[1] == '.squashfs': file = f self.dev = '/dev/loop3' else: return -1 misc.ex('losetup', self.dev, file) os.mkdir(self.source) misc.ex('mount', self.dev, self.source) return 0
def mount_target(self): """mount selected partitions on /target .""" # stderr.write ('PuntosDeMontaje: ' + str (self.mountpoints) + '\n') if not os.path.isdir(self.target) and not os.path.isfile(self.target): os.mkdir(self.target) misc.ex('mount', self.mountpoints.keys()[self.mountpoints.values().index('/')], self.target) for device, path in self.mountpoints.items(): if ( path == '/' ): continue elif ( path == 'swap' ): os.system('swapon %s' % device) continue path = os.path.join(self.target, path[1:]) if not os.path.isdir(path) and not os.path.isfile(path): os.mkdir(path) else: misc.pre_log('error', 'Problemas al crear %s' % path) if not misc.ex ('mount', '-t', 'ext3', device, path): misc.ex('mkfs.ext3',device) misc.ex('mount', device, path) if ( 'swap' not in self.mountpoints.values() ): # If swap partition isn't defined, we create a swapfile os.system("dd if=/dev/zero of=%s/swapfile bs=1024 count=%d" % (self.target, MINIMAL_PARTITION_SCHEME ['swap'] * 1024) ) os.system("mkswap %s/swapfile" % self.target) os.system("swapon %s/swapfile" % self.target) return True
def chrex(self, *args): msg = '' for word in args: msg += str(word) + ' ' if not misc.ex('chroot', self.target, *args): post_log('error', 'chroot' + msg) return False post_log('info', 'chroot' + msg) return True
def copy_logs(self): """copy logs files into installed system.""" distro = open ('/etc/lsb-release').readline ().strip ().split ('=') [1].lower () log_file = '/var/log/' + distro + '-express' if not misc.ex('cp', '-a', log_file, os.path.join(self.target, log_file[1:])): misc.pre_log('error', 'No se pudieron copiar los registros de instalaciĆ³n') return True
def configure_hardware(self): """reconfiguring several packages which depends on the hardware system in which has been installed on and need some automatic configurations to get work.""" self.chrex('mount', '-t', 'proc', 'proc', '/proc') self.chrex('mount', '-t', 'sysfs', 'sysfs', '/sys') misc.ex('cp', '/etc/X11/xorg.conf', os.path.join(self.target, 'etc/X11/xorg.conf') ) packages = ['gnome-panel', 'gnome-panel-data', 'ssh', 'linux-image-' + self.kernel_version] try: for package in packages: self.copy_debconf(package) self.reconfigure(package) finally: self.chrex('umount', '/proc') self.chrex('umount', '/sys') return True
def mount_target(self): """mount selected partitions on /target .""" # stderr.write ('PuntosDeMontaje: ' + str (self.mountpoints) + '\n') if not os.path.isdir(self.target) and not os.path.isfile(self.target): os.mkdir(self.target) misc.ex('mount', self.mountpoints.keys()[self.mountpoints.values().index('/')], self.target) for device, path in self.mountpoints.items(): if ( path == '/' ): continue elif ( path == 'swap' ): os.system('swapon %s' % device) continue elif ( path == '/home' ): path = os.path.join(self.target, path[1:]) if not os.path.isdir(path) and not os.path.isfile(path): os.makedirs(path) else: misc.pre_log('error', 'Problemas al crear %s' % path) # If we cannot mount home partition, we format it if not misc.ex ('mount', '-t', 'ext3', device, path): misc.pre_log('info','%s is not able to be mounted in /home as ext3 filesystem' % device) misc.pre_log('info','%s is going to be formated as ext3 filesystem' % device) misc.ex('mkfs.ext3', device) misc.ex('e2fsck -fy', device) misc.ex('mount', device, path) else: path = os.path.join(self.target, path[1:]) if not os.path.isdir(path) and not os.path.isfile(path): os.makedirs(path) else: misc.pre_log('error', 'Problemas al crear %s' % path) # If we cannot mount the rest of user defined partition, we leave them # as they are (without formatting), just for security if not misc.ex ('mount', '-t', 'auto', device, path): misc.pre_log('info','%s cannot be mounted ' % device) misc.pre_log('info','%s will not be formatted ' % device) return True
def chrex(self, *args): """executes commands on chroot system (provided by *args).""" msg = '' for word in args: msg += str(word) + ' ' if not misc.ex('chroot', self.target, *args): misc.post_log('error', 'chroot' + msg) return False misc.post_log('info', 'chroot' + msg) return True
def format_target(mountpoints): '''format_target(mountpoints) -> bool From mountpoints extract the devices to partition and do it. The method return true or false depends the result of this operation. ''' for path, device in mountpoints.items(): if path in ['/']: try: misc.ex('mkfs.ext3','device') except: return False elif path == 'swap': try: misc.ex('mkswap','device') except: return False return True
def format_target (self, queue): '''format_target(queue) -> bool From mountpoints extract the devices to partition and do it. The method return true or false depends the result of this operation. ''' for device, path in self.mountpoints.items(): if path in ['/']: queue.put( _("1 Formateando particiĆ³n raĆz" )) if not misc.ex('mkfs.ext3', device): return False queue.put( _("2 ParticiĆ³n raĆz lista" )) elif path == 'swap': queue.put(_( "3 Preparando particiĆ³n swap" )) if not misc.ex('mkswap', device): return False queue.put( _("3 ParticiĆ³n swap lista" ))
def mount_source(self): from os import path self.dev = "" files = ["/cdrom/casper/filesystem.cloop", "/cdrom/META/META.squashfs"] for f in files: if path.isfile(f) and path.splitext(f)[1] == ".cloop": file = f self.dev = "/dev/cloop1" elif path.isfile(f) and path.splitext(f)[1] == ".squashfs": file = f self.dev = "/dev/loop3" if self.dev == "": return False misc.ex("losetup", self.dev, file) if not os.path.isdir(self.source): os.mkdir(self.source) misc.pre_log("info", "mkdir %s" % self.source) misc.ex("mount", self.dev, self.source) return True
def configure_skel(self): """copy to target the main configuration files for user """ misc.ex('dpkg-genstatus','-g','-d',self.target) misc.ex('cp',os.path.join(self.target,'tmp/status'), os.path.join(self.target,'var/lib/dpkg/status') ) FILES=["etc/locale.gen", "etc/X11/xorg.conf", "etc/environment", "etc/network/interfaces", "etc/lsb-release"] for filename in FILES: misc.ex('cp', '/' + filename, os.path.join(self.target, filename) ) misc.ex('cp','-ar', '/etc/skel', os.path.join(self.target, 'etc/') ) return True
def format_target(self, queue): """format_target(queue) -> bool From mountpoints extract the devices to partition and do it. The method return true or false depends the result of this operation. """ misc.ex("udevstart") for device, path in self.mountpoints.items(): if path in ["/"]: queue.put("1 Formateando particiĆ³n raĆz") if not misc.ex("mkfs.ext3", device): return False misc.ex("e2fsck -fy", device) queue.put("2 ParticiĆ³n raĆz lista") elif path == "swap": queue.put("3 Preparando particiĆ³n swap") if not misc.ex("mkswap", device): return False queue.put("3 ParticiĆ³n swap lista")
def auto_partition (self, drive, steps = None, \ do_it = ACTUAL_PARTITIONING): """ Make 3 partitions automatically on the specified C{device}. When C{progress_bar} is not C{None}, it is updated dinamically as the partitioning process goes on. """ result = None if steps is not None: status = 0.1 steps.put ('%f|Iniciando el proceso de particionado automĆ”tico...' % status) status = status + 0.1 if drive.has_key ('info'): if drive ['info'].has_key ('primary'): if drive ['info'] ['primary'] < 2: # Make 3 new primary partitions? pass components = self.__partition_scheme.keys () stop = False # We suppose that there is no extended partition: ext_part = False # Initially, every new partition will be logical: try_primary = False if drive.has_key ('info'): if drive ['info'].has_key ('ext'): if drive ['info'] ['ext'] > 0: # Actually, there is already an extended partition: ext_part = True for part in components: if self.__debug: stderr.write ('auto_partition: part = "' + str (part) + '".\n') if try_primary: # Create a primary partition: required = int (round (self.__partition_scheme [part]) * 1.02) info = self.__get_info (drive ['id'], required) type = 'primaria' else: if ext_part: # A new logical partition is created. It has 2% more space # so "recycle" partitioning method is enabled if user # decides to reinstall in the same drive: required = int (round (self.__partition_scheme [part]) * 1.02) info = self.__get_info (drive ['id'], required, '-j') type = 'lĆ³gica' else: # It is necessary to create an extended partition # (with 8% more space -- 6% of 3 partitions and 2% more to be sure): required = int (round (sum (self.__partition_scheme.values ()) * 1.08)) info = self.__get_info (drive ['id'], required, '-x') components.append (part) type = 'extendida' if steps is not None: steps.put ('%f|Creando una particiĆ³n %s de %s...' % \ (status, type, beautify_size (int (required) * 1024 * 1024))) status = status + 0.1 # Now we have to decide which option is better: if info.has_key ('opts'): if self.__debug: stderr.write ('auto_partition: has_key ("opts").\n') options = info ['opts'] else: if self.__debug: stderr.write ('auto_partition: NO has_key ("opts").\n') if try_primary: # Definitively, no more partitions can be created. # Stop partitioning: if self.__debug: stderr.write ('auto_partition: stopped!\n') stop = True break else: # Next partitions should be primary, or not be at all: if self.__debug: stderr.write ('auto_partition: switching to primary.\n') components.append (part) try_primary = True continue what = -1 i = 1 while -1 == what and i <= len (options): if 'CR' == options [i - 1] [1] [:2]: what = i i = i + 1 i = 1 while -1 == what and i <= len (options): if 'RE' == options [i - 1] [1] [:2]: what = i i = i + 1 if what is -1: if self.__debug: stderr.write ('auto_partition: there are no valid options.\n') if try_primary: # Definitively, no more partitions can be created. # Stop partitioning: if self.__debug: stderr.write ('auto_partition: stopped!\n') stop = True break else: # Next partitions should be primary, or not be at all: if self.__debug: stderr.write ('auto_partition: switching to primary.\n') components.append (part) try_primary = True continue else: if try_primary: info = self.__get_info (drive ['id'], required, '-i', str (what) + '\n') else: if not ext_part: info = self.__get_info (drive ['id'], required, '-x -i', str (what) + '\n') else: info = self.__get_info (drive ['id'], required, '-j -i', str (what) + '\n') if info.has_key ('commands'): c = info ['commands'] p = Popen3 ('echo "Creando ' + str (part) + '..." >> /tmp/guadalinex-express.commands') p.wait () subprogress = 0.2 / (len (c) + 1) for i in c: # If we're going to resize NTFS, we need to force the execution of the command if "ntfsresize" in i: if ex('ntfsfix ' + str(part) + ' > /dev/null 2>&1') != 0 : stop = True break i = "yes | " + i.strip() + " -f " + "\n" if steps is not None: steps.put ('%f|Creando una particiĆ³n %s de %s...' % \ (status, type, beautify_size (int (required) * 1024 * 1024))) status = status + subprogress # Print the commands: if self.__debug: stderr.write ('auto_partition: command: "' + i.strip () + '" executed.\n') p = Popen3 ('echo "' + i.strip () + '" >> /tmp/guadalinex-express.commands') p.wait () if do_it: # Do it! Execute commands to make partitions! if 'parted ' in i and exists ('/proc/partitions'): partitions_file = file ('/proc/partitions') previous_partitions = partitions_file.read () partitions_file.close () previous_checksum = crc32 (previous_partitions) # Execute the command: p = Popen3 (i) p.wait () # Let the system be aware of the changes: if 'parted ' in i and exists ('/proc/partitions'): current_checksum = previous_checksum while current_checksum is previous_checksum: sleep (1) partitions_file = file ('/proc/partitions') current_partitions = partitions_file.read () partitions_file.close () current_checksum = crc32 (current_partitions) sleep (5) if info.has_key ('metacoms'): mc = info ['metacoms'] for i in mc: if self.__debug: stderr.write ('# ' + i) if self.__debug: stderr.write ("info.has_key ('dest') = " + str (info.has_key ('dest')) + '; ext_part = ' + str (ext_part) + '.\n') if ext_part: if info.has_key ('dest'): if result is None: result = {} result [(info ['dest']).strip ()] = part.strip () if self.__debug: stderr.write (str (part.strip ()) + \ ' added as ' + \ str ((info ['dest']).strip ()) + '\n') else: ext_part = True # During formatting and copying, "root" is known as "/", # and "home" is known as "/home", so it is necessary to # change them before passing mount point associations to # the backend: if steps is not None: steps.put ('%f|Terminando el proceso de particionado...' % status) if stop: result = 'STOPPED' else: for i in result.keys (): if 'root' == result [i].lower (): result [i] = '/' elif 'home' == result [i].lower (): result [i] = '/home' if self.__debug: stderr.write ('auto_partition: result = "' + str (result) + '".\n') return result
def copy_logs(self): try: misc.ex("cp", "-a", "/var/log/installer", os.path.join(self.target, "/var/log/installer")) except IOError, error: misc.pre_log("error", error) return False
def unmount_source(self): if not misc.ex("umount", self.source): return False if not misc.ex("losetup", "-d", self.dev): return False return True
def unmount_source(self): if not misc.ex('umount', self.source): return False if not misc.ex('losetup', '-d', self.dev): return False return True
from os import path self.dev = '' if not os.path.isdir(self.source): try: os.mkdir(self.source) except Exception, e: print e misc.pre_log('info', 'mkdir %s' % self.source) # Autodetection on unionfs systems file = open('/proc/mounts').readlines() for line in file: if ( line.split()[2] == 'squashfs' ): misc.ex('mount', '--bind', line.split()[1], self.source) self.unionfs = True return True # Manual Detection on non unionfs systems files = ['/cdrom/casper/filesystem.cloop', '/cdrom/META/META.squashfs'] for file in files: if path.isfile(file) and path.splitext(file)[1] == '.cloop': self.dev = '/dev/cloop1' break elif path.isfile(file) and path.splitext(file)[1] == '.squashfs': self.dev = '/dev/loop3' break if self.dev == '':
def unmount_source(self): misc.ex('umount', self.source) misc.ex('losetup', '-d', self.dev)
def copy_debconf(self, package): targetdb = os.path.join(self.target, 'var/cache/debconf/config.dat') misc.ex('debconf-copydb', 'configdb', 'targetdb', '-p', '^%s/' % package, '--config=Name:targetdb', '--config=Driver:File','--config=Filename:' + targetdb)
from os import path self.dev = '' if not os.path.isdir(self.source): try: os.mkdir(self.source) except Exception, e: print e misc.pre_log('info', 'mkdir %s' % self.source) # Autodetection on unionfs systems file = open('/proc/mounts').readlines() for line in file: if (line.split()[2] == 'squashfs'): misc.ex('mount', '--bind', line.split()[1], self.source) self.unionfs = True return True # Manual Detection on non unionfs systems files = ['/cdrom/casper/filesystem.cloop', '/cdrom/META/META.squashfs'] for file in files: if path.isfile(file) and path.splitext(file)[1] == '.cloop': self.dev = '/dev/cloop1' break elif path.isfile(file) and path.splitext(file)[1] == '.squashfs': self.dev = '/dev/loop3' break if self.dev == '':
def copy_logs(self): try: misc.ex('cp', '-a', '/var/log/installer', os.path.join(self.target,'/var/log/installer')) except IOError, error: misc.pre_log('error', error) return False
def configure_network(self): misc.ex('/usr/share/setup-tool-backends/scripts/network-conf','--get', '>',self.target + '/tmp/network.xml') self.chex('/usr/share/setup-tool-backends/scripts/network-conf','--set', '<','/tmp/network.xml')
def configure_bootloader(self): """configuring and installing boot loader into installed hardware system.""" import re target_dev = self.mountpoints.keys()[self.mountpoints.values().index('/')] distro = self.distro.capitalize() misc.ex('mount', '/proc', '--bind', self.target + '/proc') misc.ex('mount', '/sys', '--bind', self.target + '/sys') misc.ex('mount', '/dev', '--bind', self.target + '/dev') if not os.path.exists(self.target + '/boot/grub'): os.mkdir(self.target + '/boot/grub') #/target/etc/mtab creation - temporary bugfix for buggy grub-install mtab = open(os.path.join(self.target,'etc/mtab'), 'w') print >>mtab, '%s\t%s\t%s\t%s\t%s' % (target_dev, '/', 'auto', 'defaults', '0 0') mtab.close() #grub-install it's enough, because it calls grub-shell with setup command #device_regex = re.compile(r'/dev/[a-z]+') #device = device_regex.search(target_dev).group() #if not os.path.exists ( device ) or os.path.isdir ( device ): # device = target_dev self.chrex ('rm', '-f', '/boot/grub/device.map') #self.chrex ('grub-install', device ) self.chrex ('grub-install', 'hd0') # creates grub menu.lst on target self.chrex ('rm', '-f', '/boot/grub/menu.lst') #self.chrex('update-grub', '-y') # guess root device for ele in self.mountpoints.items(): if ele[1]=="/": root_device=ele[0] break self.chrex('/usr/lib/python2.4/site-packages/ue/backend/grub-config.sh', root_device) misc.ex('umount', '-f', self.target + '/proc') misc.ex('umount', '-f', self.target + '/sys') misc.ex('umount', '-f', self.target + '/dev') return True
def configure_bootloader(self): """configuring and installing boot loader into installed hardware system.""" import re target_dev = self.mountpoints.keys()[self.mountpoints.values().index( '/')] distro = self.distro.capitalize() misc.ex('mount', '/proc', '--bind', self.target + '/proc') misc.ex('mount', '/sys', '--bind', self.target + '/sys') misc.ex('mount', '/dev', '--bind', self.target + '/dev') if not os.path.exists(self.target + '/boot/grub'): os.mkdir(self.target + '/boot/grub') #/target/etc/mtab creation - temporary bugfix for buggy grub-install mtab = open(os.path.join(self.target, 'etc/mtab'), 'w') print >> mtab, '%s\t%s\t%s\t%s\t%s' % (target_dev, '/', 'auto', 'defaults', '0 0') mtab.close() #grub-install it's enough, because it calls grub-shell with setup command device_regex = re.compile(r'/dev/[a-z]+') device = device_regex.search(target_dev).group() if not os.path.exists(device) or os.path.isdir(device): device = target_dev self.chrex('rm', '-f', '/boot/grub/device.map') self.chrex('grub-install', device) # creates grub menu.lst on target self.chrex('rm', '-f', '/boot/grub/menu.lst') #self.chrex('update-grub', '-y') # guess root device for ele in self.mountpoints.items(): if ele[1] == "/": root_device = ele[0] break self.chrex( '/usr/lib/python2.4/site-packages/ue/backend/grub-config.sh', root_device) misc.ex('umount', '-f', self.target + '/proc') misc.ex('umount', '-f', self.target + '/sys') misc.ex('umount', '-f', self.target + '/dev') return True
def copy_debconf(self, package): """setting debconf database into installed system.""" targetdb = os.path.join(self.target, 'var/cache/debconf/config.dat') misc.ex('debconf-copydb', 'configdb', 'targetdb', '-p', '^%s/' % package, '--config=Name:targetdb', '--config=Driver:File','--config=Filename:' + targetdb)
file = open('/proc/mounts').readlines() dirs={} for line in file: if ( line.split()[2] == 'squashfs' ): #misc.ex('mount', '--bind', line.split()[1], self.source) dirs[line.split()[0]]=line.split()[1] self.unionfs = True keys = dirs.keys() keys.sort() keys.pop() keys.reverse() minuso='dirs=' for dev in keys: minuso=minuso + dirs[dev] + '=ro:' misc.ex('mount','-t','unionfs','-o',minuso,'unionfs',self.source) return True # Manual Detection on non unionfs systems files = ['/cdrom/casper/filesystem.cloop', '/cdrom/META/META.squashfs'] for file in files: if path.isfile(file) and path.splitext(file)[1] == '.cloop': self.dev = '/dev/cloop1' break elif path.isfile(file) and path.splitext(file)[1] == '.squashfs': self.dev = '/dev/loop3' break if self.dev == '': return False