def on_btnLocalize_clicked(self, widget):
     # Set locale
     selected = self.tvHandlerDistros.getToggledValues(toggleColNr=0, valueColNr=2)
     for path in selected:
         rootPath = "%s/root" % path
         de = EditDistro(path)
         script = "setlocale.sh"
         scriptSource = join(self.scriptDir, "files/{}".format(script))
         scriptTarget = join(rootPath, script)
         if exists(scriptSource):
             copy(scriptSource, scriptTarget)
             self.ec.run("chmod a+x '%s'" % scriptTarget)
             de.openTerminal("/bin/bash %s" % script)
             silent_remove(scriptTarget)
         
         # Copy Grub locale files to ISO boot directory and configure grub.cfg
         grub_path = "%s/boot/boot/grub/" % path
         grubcfg_path = "%s/grub.cfg" % grub_path
         locale_path = "%s/root/boot/grub/locale" % path
         default_path = "%s/root/etc/default" % path
         locale = self.ec.run("grep -oP '(?<=LANG=).*?(?=\.)' %s/locale" % default_path)[0]
         if exists(locale_path) and \
            exists(grubcfg_path) and \
            locale:
             self.ec.run("cp -rf %s %s" % (locale_path, grub_path))
             self.ec.run("sed -i 's/set lang=.*/set lang=%s/' %s" % (locale, grubcfg_path))
 def download_offline_packages(self, path):
     rootPath = "%s/root" % path
     arch = getGuestEfiArchitecture(rootPath)
     de = EditDistro(path)
     script = "offline.sh"
     scriptSource = join(self.scriptDir, "files/{}".format(script))
     scriptTarget = join(rootPath, script)
     offlineSource = join(rootPath, "offline")
     offlineTarget = join(rootPath, "../boot/offline")
     if exists(scriptSource):
         try:
             copy(scriptSource, scriptTarget)
             self.ec.run("chmod a+x '%s'" % scriptTarget)
             # Run the script
             de.openTerminal("/bin/bash {} {}".format(script, arch))
             # Remove script
             silent_remove(scriptTarget)
             # Move offline directory to boot directory
             if exists(offlineSource):
                 print(("%s exists" % offlineSource))
                 if exists(offlineTarget):
                     print((">> Remove %s" % offlineTarget))
                     silent_remove(offlineTarget)
                 print((">> Move %s to %s" % (offlineSource, offlineTarget)))
                 move(offlineSource, offlineTarget)
             else:
                 print((">> Cannot find: %s" % offlineSource))
         except Exception as detail:
             self.showError("Error: getting offline packages", detail, self.window)
     else:
         print((">> Cannot find: %s" % scriptSource))
    def on_btnUpgrade_clicked(self, widget):
        selected = self.tvHandlerDistros.getToggledValues(toggleColNr=0, valueColNr=2)
        upgraded = False
        for path in selected:
            upgraded = True
            rootPath = "%s/root" % path
            force = get_apt_force(rootPath)
            de = EditDistro(path)
            de.openTerminal("apt-get update")
            if exists(join(rootPath, 'etc/apache2/apache2.conf')):
                de.openTerminal("service apache2 start")
            if exists(join(rootPath, 'etc/mysql/debian.cnf')):
                de.openTerminal("service mysql start")
            de.openTerminal("apt-get -y %s -o Dpkg::Options::=\"--force-confnew\" dist-upgrade" % force)
            if exists(join(rootPath, 'etc/apache2/apache2.conf')):
                de.openTerminal("service apache2 stop")
            if exists(join(rootPath, 'etc/mysql/debian.cnf')):
                de.openTerminal("service mysql stop")

            # Cleanup old kernel and headers
            script = "rmoldkernel.sh"
            scriptSource = join(self.scriptDir, "files/{}".format(script))
            scriptTarget = join(rootPath, script)
            if exists(scriptSource):
                copy(scriptSource, scriptTarget)
                self.ec.run("chmod a+x '%s'" % scriptTarget)
                de.openTerminal("/bin/bash %s" % script)
                silent_remove(scriptTarget)

            # Download offline packages
            print(">> Start downloading offline packages")
            self.download_offline_packages(path)

        if upgraded and exists("/usr/bin/aplay") and exists(self.doneWav):
            self.ec.run("/usr/bin/aplay '%s'" % self.doneWav, False)
 def on_btnLocalize_clicked(self, widget):
     # Set locale
     selected = self.tvHandlerDistros.getToggledValues(toggleColNr=0, valueColNr=2)
     for path in selected:
         rootPath = "%s/root" % path
         de = EditDistro(path)
         script = "setlocale.sh"
         scriptSource = join(self.scriptDir, "files/{}".format(script))
         scriptTarget = join(rootPath, script)
         if exists(scriptSource):
             copy(scriptSource, scriptTarget)
             self.ec.run("chmod a+x %s" % scriptTarget)
             de.openTerminal("/bin/bash %s" % script)
             silent_remove(scriptTarget)
Example #5
0
 def on_btnLocalize_clicked(self, widget):
     # Set locale
     selected = self.tvHandlerDistros.getToggledValues(toggleColNr=0,
                                                       valueColNr=2)
     for path in selected:
         rootPath = "%s/root" % path
         de = EditDistro(path)
         script = "setlocale.sh"
         scriptSource = join(self.scriptDir, "files/{}".format(script))
         scriptTarget = join(rootPath, script)
         if exists(scriptSource):
             copy(scriptSource, scriptTarget)
             self.ec.run("chmod a+x '%s'" % scriptTarget)
             de.openTerminal("/bin/bash %s" % script)
             silent_remove(scriptTarget)
Example #6
0
    def on_btnUpgrade_clicked(self, widget):
        selected = self.tvHandlerDistros.getToggledValues(toggleColNr=0,
                                                          valueColNr=2)
        upgraded = False
        for path in selected:
            upgraded = True
            rootPath = "%s/root" % path
            force = get_apt_force(rootPath)
            de = EditDistro(path)
            de.openTerminal("apt-get update")
            if exists(join(rootPath, 'etc/apache2/apache2.conf')):
                de.openTerminal("service apache2 start")
            if exists(join(rootPath, 'etc/mysql/debian.cnf')):
                de.openTerminal("service mysql start")
            de.openTerminal(
                "apt-get -y %s -o Dpkg::Options::=\"--force-confnew\" dist-upgrade"
                % force)
            if exists(join(rootPath, 'etc/apache2/apache2.conf')):
                de.openTerminal("service apache2 stop")
            if exists(join(rootPath, 'etc/mysql/debian.cnf')):
                de.openTerminal("service mysql stop")

            # Cleanup old kernel and headers
            script = "rmoldkernel.sh"
            scriptSource = join(self.scriptDir, "files/{}".format(script))
            scriptTarget = join(rootPath, script)
            if exists(scriptSource):
                copy(scriptSource, scriptTarget)
                self.ec.run("chmod a+x '%s'" % scriptTarget)
                de.openTerminal("/bin/bash %s" % script)
                silent_remove(scriptTarget)

            # Download offline packages
            print(">> Start downloading offline packages")
            self.download_offline_packages()

        if upgraded and exists("/usr/bin/aplay") and exists(self.doneWav):
            self.ec.run("/usr/bin/aplay '%s'" % self.doneWav, False)
Example #7
0
 def download_offline_packages(self):
     selected = self.tvHandlerDistros.getToggledValues(toggleColNr=0,
                                                       valueColNr=2)
     for path in selected:
         rootPath = "%s/root" % path
         arch = getGuestEfiArchitecture(rootPath)
         de = EditDistro(path)
         script = "offline.sh"
         scriptSource = join(self.scriptDir, "files/{}".format(script))
         scriptTarget = join(rootPath, script)
         offlineSource = join(rootPath, "offline")
         offlineTarget = join(rootPath, "../boot/offline")
         if exists(scriptSource):
             try:
                 copy(scriptSource, scriptTarget)
                 self.ec.run("chmod a+x '%s'" % scriptTarget)
                 # Run the script
                 de.openTerminal("/bin/bash {} {}".format(script, arch))
                 # Remove script
                 silent_remove(scriptTarget)
                 # Move offline directory to boot directory
                 if exists(offlineSource):
                     print(("%s exists" % offlineSource))
                     if exists(offlineTarget):
                         print((">> Remove %s" % offlineTarget))
                         silent_remove(offlineTarget)
                     print((">> Move %s to %s" %
                            (offlineSource, offlineTarget)))
                     move(offlineSource, offlineTarget)
                 else:
                     print((">> Cannot find: %s" % offlineSource))
             except Exception as detail:
                 self.showError("Error: getting offline packages", detail,
                                self.window)
         else:
             print((">> Cannot find: %s" % scriptSource))
Example #8
0
    def openTerminal(self, command=""):
        # Set some paths
        resolveCnfHost = "/etc/resolv.conf"
        resolveCnf = join(self.rootPath, "etc/resolv.conf")
        resolveCnfBak = "%s.bk" % resolveCnf
        wgetrc = join(self.rootPath, "etc/wgetrc")
        wgetrcBak = "%s.bk" % wgetrc
        terminal = "/tmp/constructor-terminal.sh"
        lockDir = join(self.rootPath, "run/lock/")
        proc = join(self.rootPath, "proc/")
        dev = join(self.rootPath, "dev/")
        pts = join(self.rootPath, "dev/pts/")
        sys = join(self.rootPath, "sys/")
        policy = join(self.rootPath, "usr/sbin/policy-rc.d")
        ischroot = join(self.rootPath, "usr/bin/ischroot")
        ischrootTmp = join(self.rootPath, "usr/bin/ischroot.tmp")

        try:
            # temporary create /run/lock
            if not exists(lockDir):
                makedirs(lockDir)

            # setup environment
            # copy dns info
            if exists(resolveCnf):
                move(resolveCnf, resolveCnfBak)
            if exists(resolveCnfHost):
                copy(resolveCnfHost, resolveCnf)

            # umount /proc /dev /dev/pts /sys
            self.unmount([pts, dev, proc, sys])

            # mount /proc /dev /dev/pts /sys /run /sys
            self.ec.run("mount --bind /proc '%s'" % proc)
            self.ec.run("mount --bind /dev '%s'" % dev)
            self.ec.run("mount --bind /dev/pts '%s'" % pts)
            self.ec.run("mount --bind /sys '%s'" % sys)

            # copy wgetrc
            move(wgetrc, wgetrcBak)
            copy("/etc/wgetrc", wgetrc)

            # Let dpkg only start daemons when desired
            scr = "#!/bin/sh\nexit 101\n"
            with open(policy, 'w') as f:
                f.write(scr)
            self.ec.run("chmod a+x '%s'" % policy)

            # Temporary fix ischroot
            if not exists(ischrootTmp):
                self.ec.run("mv '%s' '%s'" % (ischroot, ischrootTmp))
            if not exists(ischroot):
                self.ec.run("ln -s /bin/true '%s'" % ischroot)

            # HACK: create temporary script for chrooting
            silent_remove(terminal)
            scr = "#!/bin/sh\nchroot '%s' %s\n" % (self.rootPath, command)
            with open(terminal, 'w') as f:
                f.write(scr)
            self.ec.run("chmod a+x '%s'" % terminal)
            if exists("/usr/bin/xterm"):
                self.ec.run('export HOME=/root ; xterm -bg black -fg white -rightbar -title \"%s\" -e %s' % (self.description, terminal))
            elif self.ec.run('which x-terminal-emulator'):
                # use x-terminal-emulator if xterm isn't available
                self.ec.run('export HOME=/root ; x-terminal-emulator -e %s' % terminal)
            else:
                print('Error: no valid terminal found')

            # restore wgetrc
            move(wgetrcBak, wgetrc)

            # move dns info
            if exists(resolveCnfBak):
                move(resolveCnfBak, resolveCnf)
            else:
                silent_remove(resolveCnf)

            # umount /proc /dev /dev/pts /sys
            self.unmount([pts, dev, proc, sys])

            # remove temp script
            silent_remove(terminal)

            # remove policy script
            silent_remove(policy)

            # replace ischroot
            if exists("%s.tmp" % ischroot):
                self.ec.run("rm '%s'" % ischroot)
                self.ec.run("mv '%s.tmp' '%s'" % (ischroot, ischroot))

            # cleanup /run
            self.ec.run("rm -rf '%s/run/'*" % self.rootPath)

        except Exception as detail:
            # restore wgetrc
            move(wgetrcBak, wgetrc)

            # move dns info
            if exists(resolveCnfBak):
                move(resolveCnfBak, resolveCnf)
            else:
                silent_remove(resolveCnf)

            # umount /proc /dev /dev/pts /sys
            self.unmount([pts, dev, proc, sys])

            # remove temp script
            silent_remove(terminal)

            # remove policy script
            silent_remove(policy)

            # replace ischroot
            if exists("%s.tmp" % ischroot):
                self.ec.run("rm '%s'" % ischroot)
                self.ec.run("mv '%s.tmp' '%s'" % (ischroot, ischroot))

            # cleanup /run
            self.ec.run("rm -rf '%s/run/'*" % self.rootPath)

            errText = 'Error launching terminal: '
            print((errText, detail))
Example #9
0
    def build_efi_image(self, distro_path):
        hostEfiArchitecture = getHostEfiArchitecture()
        if hostEfiArchitecture == "":
            return None

        # TODO - also 32-bit installs (haven't tested this)

        modules = "part_gpt part_msdos ntfs ntfscomp hfsplus fat ext2 chain boot configfile linux " \
                "multiboot iso9660 gfxmenu gfxterm loadenv efi_gop efi_uga loadbios fixvideo png " \
                "loopback search minicmd cat cpuid appleldr elf usb videotest " \
                "halt help ls reboot echo test normal sleep memdisk tar font video_fb video " \
                "gettext true video_bochs video_cirrus multiboot2 acpi gfxterm_background gfxterm_menu"

        rootPath = join(distro_path, "root")
        bootPath = join(distro_path, "boot")
        efiPath = join(distro_path, "EFI/BOOT")
        arch = getGuestEfiArchitecture(rootPath)

        grubEfiName = "bootx64"
        if arch != "x86_64":
            arch = "i386"
            grubEfiName = "bootia32"

        try:
            # Clean up old stuff and prepare for a new EFI image
            if not exists(efiPath):
                makedirs(efiPath)
            silent_remove(join(bootPath, "efi"))
            silent_remove(join(bootPath, "boot/memdisk"))
            silent_remove(join(bootPath, "boot/grub/x86_64-efi"))
            silent_remove(join(bootPath, "boot/grub/i386-efi"))
            silent_remove(join(bootPath, "boot/grub/efi.img"))
            silent_remove(join(bootPath, "boot/grub/loopback.cfg"))

            # Create embedded.cfg
            cont = """search --file --set=root /MD5SUMS
if [ -e ($root)/boot/grub/grub.cfg ]; then
  set prefix=($root)/boot/grub
  configfile $prefix/grub.cfg
else
  echo "Could not find /boot/grub/grub.cfg!"
fi
"""
            with open('embedded.cfg', 'w') as f:
                f.write(cont)

            # Create the .efi image with the embedded.cfg file
            # Prefix is needed but can be left empty: it is set in embedded.cfg
            self.ec.run("grub-mkimage "
                        "--prefix '' "
                        "--config 'embedded.cfg' "
                        "-O {}-efi "
                        "-o '{}/{}.efi' "
                        "{}".format(arch, efiPath, grubEfiName, modules))

            print((">> Finished building EFI files"))
            return None

        except Exception as detail:
            return detail
Example #10
0
    def run(self):
        try:
            if not exists(self.mountDir):
                print(("Create mount directory: %s" % self.mountDir))
                makedirs(self.mountDir)

            rootDir = join(self.unpackDir, "root")
            if not exists(rootDir):
                print(("Create root directory: %s" % rootDir))
                makedirs(rootDir)

            isolinuxDir = join(self.unpackDir, "boot/isolinux")
            if not exists(isolinuxDir):
                print(("Create isolinux directory: %s" % isolinuxDir))
                makedirs(isolinuxDir)

            liveDir = join(self.unpackDir, "boot/live")
            if not exists(liveDir):
                print(("Create liveDir directory: %s" % liveDir))
                makedirs(liveDir)

            # Mount the ISO
            system("mount -o loop '%s' '%s'" % (self.unpackIso, self.mountDir))

            # Check isolinux directory
            mountIsolinux = join(self.mountDir, "isolinux")
            if not exists(mountIsolinux):
                self.ec.run("umount --force '%s'" % self.mountDir)
                self.returnMessage = "ERROR: Cannot find isolinux directory in ISO"

            fixCfgCmd = None
            dirs = []
            mountSquashfs = None
            if self.returnMessage is None:
                subdirs = self.getDirectSubDirectories(self.mountDir)
                for subdir in subdirs:
                    if self.hasSquashFs(join(self.mountDir, subdir)):
                        mountSquashfs = join(self.mountDir, subdir)
                        if subdir != "live":
                            fixCfgCmd = "sed -i 's/\/%s/\/live/g' '%s/isolinux.cfg'" % (subdir, isolinuxDir)
                    elif subdir != "isolinux":
                        dirs.append(join(self.mountDir, subdir))

                if mountSquashfs is None:
                    self.ec.run("umount --force '%s'" % self.mountDir)
                    self.returnMessage = "ERROR: Cannot find squashfs directory in ISO"

            if self.returnMessage is None:
                # Copy files from ISO to unpack directory
                for d in dirs:
                    self.ec.run("rsync -at --del '%s' '%s'" % (d, join(self.unpackDir, "boot/")))
                self.ec.run("rsync -at --del '%s/' '%s'" % (mountIsolinux, isolinuxDir))
                self.ec.run("rsync -at --del '%s/' '%s'" % (mountSquashfs, liveDir))
                self.ec.run("umount --force '%s'" % self.mountDir)

                if fixCfgCmd is not None:
                    self.ec.run(fixCfgCmd)

                # copy squashfs root
                squashfs = join(liveDir, "filesystem.squashfs")
                if exists(squashfs):
                    self.ec.run("mount -t squashfs -o loop '%s' '%s'" % (squashfs, self.mountDir))
                    self.ec.run("rsync -at --del '%s/' '%s/'" % (self.mountDir, rootDir))
                    self.ec.run("umount --force '%s'" % self.mountDir)

                # Cleanup
                silent_remove(self.mountDir, False)
                # set proper permissions
                self.ec.run("chmod 6755 '%s'" % join(rootDir, "usr/bin/sudo"))
                self.ec.run("chmod 0440 '%s'" % join(rootDir, "etc/sudoers"))

                self.returnMessage = "DONE - ISO unpacked to: %s" % self.unpackDir

            self.queue.put(self.returnMessage)

        except Exception as detail:
            self.ec.run("umount --force '%s'" % self.mountDir)
            silent_remove(self.mountDir, False)
            self.returnMessage = "ERROR: IsoUnpack: %(detail)s" % {"detail": detail}
            self.queue.put(self.returnMessage)
Example #11
0
    def run(self):
        try:
            if not exists(self.rootPath):
                self.returnMessage = "ERROR: Cannot find root directory: %s" % self.rootPath

            if not exists(self.bootPath):
                self.returnMessage = "ERROR: Cannot find boot directory: %s" % self.bootPath

            if self.returnMessage is None:
                print("======================================================")
                print("INFO: Cleanup and prepare ISO build...")
                print("======================================================")

                # Clean-up
                script = "cleanup.sh"
                scriptSource = join(self.scriptDir, "files/{}".format(script))
                scriptTarget = join(self.rootPath, script)
                if exists(scriptSource):
                    self.copy_file(scriptSource, scriptTarget)
                    self.ec.run("chmod a+x '%s'" % scriptTarget)
                    self.ed.openTerminal("/bin/bash '%s'" % script)
                    silent_remove(scriptTarget)

                rootHome = join(self.rootPath, "root")
                nanoHist = join(rootHome, ".nano_history")
                silent_remove(nanoHist)
                bashHist = join(rootHome, ".bash_history")
                silent_remove(bashHist)

                # Config naming
                regExp = "solyd.*(\d{6}|-bit)"
                d = datetime.now()
                dateString = d.strftime("%Y%m")
                nameString = "{} {}".format(self.isoName, dateString)

                # write iso name to boot/isolinux/isolinux.cfg
                cfgFile = join(self.bootPath, "isolinux/isolinux.cfg")
                if exists(cfgFile):
                    content = ""
                    with open(cfgFile, 'r') as f:
                        content = f.read()
                    if content != "":
                        content = re.sub(regExp, nameString, content, flags=re.IGNORECASE)
                        # Make sure that the paths are correct (correcting very old stuff)
                        content = re.sub('.lz', '.img', content)
                        content = re.sub('/solydxk/', '/live/', content)
                        with open(cfgFile, 'w') as f:
                            f.write(content)

                # Write info for grub (EFI)
                grubFile = join(self.bootPath, "boot/grub/grub.cfg")
                if exists(grubFile):
                    content = ""
                    with open(grubFile, 'r') as f:
                        content = f.read()
                    if content != "":
                        content = re.sub(regExp, nameString, content, flags=re.IGNORECASE)
                        with open(grubFile, 'w') as f:
                            f.write(content)

                # Vmlinuz
                vmlinuzSymLink = join(self.distroPath, "root/vmlinuz")
                if lexists(vmlinuzSymLink):
                    vmlinuzFile = self.ec.run("ls -al '%s' | cut -d'>' -f2" % vmlinuzSymLink)[0].strip()
                else:
                    self.returnMessage = "ERROR: %s not found" % vmlinuzSymLink

            if self.returnMessage is None:
                vmlinuzPath = join(self.distroPath, "root/%s" % vmlinuzFile)
                if exists(vmlinuzPath):
                    print("Copy vmlinuz")
                    self.copy_file(vmlinuzPath, join(self.livePath, "vmlinuz"))
                else:
                    self.returnMessage = "ERROR: %s not found" % vmlinuzPath

            if self.returnMessage is None:
                # Initrd
                initrdSymLink = join(self.distroPath, "root/initrd.img")
                if lexists(initrdSymLink):
                    initrdFile = self.ec.run("ls -al '%s' | cut -d'>' -f2" % initrdSymLink)[0].strip()
                else:
                    self.returnMessage = "ERROR: %s not found" % initrdSymLink

            if self.returnMessage is None:
                initrdPath = join(self.distroPath, "root/%s" % initrdFile)
                if exists(initrdPath):
                    print("Copy initrd")
                    self.copy_file(initrdPath, join(self.livePath, "initrd.img"))
                else:
                    self.returnMessage = "ERROR: %s not found" % initrdPath

            if self.returnMessage is None:
                print("======================================================")
                print("INFO: Start building ISO...")
                print("======================================================")

                # build squash root
                print("Creating SquashFS root...")
                print("Updating File lists...")
                dpkgQuery = ' dpkg -l | awk \'/^ii/ {print $2, $3}\' | sed -e \'s/ /\t/g\' '
                self.ec.run('chroot \"' + self.rootPath + '\"' + dpkgQuery + ' > \"' + join(self.livePath, "filesystem.packages") + '\"' )

                # check for existing squashfs root
                print("Removing existing SquashFS root...")
                silent_remove(join(self.livePath, "filesystem.squashfs"))
                print("Building SquashFS root...")
                # check for custom mksquashfs (for multi-threading, new features, etc.)
                mksquashfs = self.ec.run(cmd="echo $MKSQUASHFS", returnAsList=False).strip()
                rootPath = join(self.distroPath, "root/")
                squashfsPath = join(self.livePath, "filesystem.squashfs")
                if mksquashfs == '' or mksquashfs == 'mksquashfs':
                    try:
                        cpus = int(int(self.ec.run("grep ^cpu\\\s*cores /proc/cpuinfo | grep -o [0-9]* | uniq", False, False)) / 2)
                        if cpus < 1: cpus = 1
                    except:
                        cpus = 1
                    # Get excluded dirs/files
                    excludes_lst = join(self.scriptDir, "files/excludes")
                    squash_excl_str = '-wildcards -ef "{0}"'.format(excludes_lst) if exists(excludes_lst) else ''
                    cmd = "mksquashfs \"{0}\" \"{1}\" -comp xz -processors {2} {3}".format(rootPath, squashfsPath, cpus, squash_excl_str)
                else:
                    cmd = "{0} \"{1}\" \"{2}\"".format(mksquashfs, rootPath, squashfsPath)
                self.ec.run(cmd)

                # Update isolinux files
                syslinuxPath = join(self.rootPath, "usr/lib/syslinux")
                modulesPath = join(syslinuxPath, "modules/bios")
                isolinuxPath = join(self.bootPath, "isolinux")
                self.ec.run("chmod -R +w '%s'" % isolinuxPath)
                cat = join(isolinuxPath, "boot.cat")
                silent_remove(cat)
                self.copy_file(join(modulesPath, "chain.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "hdt.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libmenu.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libgpl.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "reboot.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "vesamenu.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "poweroff.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "ldlinux.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libcom32.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libutil.c32"), isolinuxPath)
                self.copy_file(join(self.rootPath, "boot/memtest86+.bin"), join(isolinuxPath, "memtest86"))
                self.copy_file("/usr/lib/ISOLINUX/isolinux.bin", isolinuxPath)

                # Build the EFI image
                efi_error = self.build_efi_image(self.distroPath)
                if efi_error is not None:
                    self.returnMessage = "ERROR: BuildIso: %(efi_error)s" % {"efi_error": efi_error}

                # Create efiboot.img
                efiPath = join(self.distroPath, "EFI")
                efibootPath = join(isolinuxPath, "efiboot.img")
                print(("Create %s" % efibootPath))
                cmd = "rm '%s' 2>/dev/null;" \
                      "mkdosfs -F12 -n \"SOLYDXK_EFI\" -C '%s' 2048;" \
                      "mcopy -s -i '%s' '%s' ::" % (efibootPath, efibootPath, efibootPath, efiPath)
                self.ec.run(cmd)

                # Check if the .solydxk file for Grub exists
                grubChkFile = join(self.bootPath, ".solydxk")
                if exists(grubChkFile):
                    #system("touch '%s'" % grubChkFile)
                    silent_remove(grubChkFile)

                # remove existing iso
                silent_remove(self.isoFileName)

                # Create an md5sum file for the isolinux/grub integrity check
                md5sum_fle = 'MD5SUMS'
                skip_fls = [md5sum_fle, 'isolinux.bin']
                md5sum_lst = []
                files = [file for file in glob.glob(self.bootPath + '/**', recursive=True)] + \
                        [file for file in glob.glob(self.bootPath +'/.**', recursive=True)]
                for file in files:
                    if not isdir(file) and not basename(file) in skip_fls:
                        md5 = self.ec.run("md5sum %s" % file, False, False)
                        if md5:
                            md5sum_lst.append(md5.replace(self.bootPath, '.'))
                if md5sum_lst:
                    md5_cont = '\n'.join(md5sum_lst) + '\n'
                    with open(join(self.bootPath, md5sum_fle), 'w') as f:
                        f.write(md5_cont)

                # build iso according to architecture
                print("Building ISO...")

                cmd = "xorriso -as mkisofs " \
                      "-r " \
                      "-volid '%s' " \
                      "-o '%s' " \
                      "-isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin " \
                      "-partition_offset 16 " \
                      "-J " \
                      "-l " \
                      "-joliet-long " \
                      "-c isolinux/boot.cat " \
                      "-b isolinux/isolinux.bin " \
                      "-no-emul-boot " \
                      "-boot-load-size 4 " \
                      "-boot-info-table " \
                      "-eltorito-alt-boot " \
                      "-e isolinux/efiboot.img " \
                      "-no-emul-boot " \
                      "-isohybrid-gpt-basdat " \
                      "'%s'" % (self.get_volid(self.isoName), self.isoFileName, self.bootPath)
                self.ec.run(cmd)

                print("Insert md5 in ISO")
                self.ec.run("implantisomd5 '%s'" % self.isoFileName)

                print("Create sha256 file...")
                oldmd5 = "%s.md5" % self.isoFileName
                silent_remove(oldmd5)
                self.ec.run("echo \"$(sha256sum \"%s\" | cut -d' ' -f 1)  %s\" > \"%s.sha256\"" % (self.isoFileName, self.isoBaseName, self.isoFileName))

                print("Create Torrent file...")
                torrentFile = "%s.torrent" % self.isoFileName
                silent_remove(torrentFile)
                self.ec.run("mktorrent -a \"%s\" -c \"%s\" -w \"%s\" -o \"%s\" \"%s\"" % (self.trackers, self.isoName, self.webseeds, torrentFile, self.isoFileName))

                print("======================================================")
                if self.returnMessage is None:
                    self.returnMessage = "DONE - ISO Located at: %s" % self.isoFileName
                print((self.returnMessage))
                print("======================================================")

            self.queue.put(self.returnMessage)

        except Exception as detail:
            self.returnMessage = "ERROR: BuildIso: %(detail)s" % {"detail": detail}
            self.queue.put(self.returnMessage)
Example #12
0
    def openTerminal(self, command=""):
        # Set some paths
        resolveCnfHost = "/etc/resolv.conf"
        resolveCnf = join(self.rootPath, "etc/resolv.conf")
        resolveCnfBak = "%s.bak" % resolveCnf
        wgetrc = join(self.rootPath, "etc/wgetrc")
        wgetrcBak = "%s.bak" % wgetrc
        terminal = "/tmp/constructor-terminal.sh"
        lockDir = join(self.rootPath, "run/lock/")
        proc = join(self.rootPath, "proc/")
        dev = join(self.rootPath, "dev/")
        pts = join(self.rootPath, "dev/pts/")
        sys = join(self.rootPath, "sys/")
        policy = join(self.rootPath, "usr/sbin/policy-rc.d")
        ischroot = join(self.rootPath, "usr/bin/ischroot")
        ischrootTmp = join(self.rootPath, "usr/bin/ischroot.tmp")

        try:
            # temporary create /run/lock
            if not exists(lockDir):
                makedirs(lockDir)

            # setup environment
            # copy dns info
            if exists(resolveCnf):
                move(resolveCnf, resolveCnfBak)
            if exists(resolveCnfHost):
                copy(resolveCnfHost, resolveCnf)

            # umount /proc /dev /dev/pts /sys
            self.unmount([pts, dev, proc, sys])

            # mount /proc /dev /dev/pts /sys /run /sys
            self.ec.run("mount --bind /proc '%s'" % proc)
            self.ec.run("mount --bind /dev '%s'" % dev)
            self.ec.run("mount --bind /dev/pts '%s'" % pts)
            self.ec.run("mount --bind /sys '%s'" % sys)

            # copy wgetrc
            move(wgetrc, wgetrcBak)
            copy("/etc/wgetrc", wgetrc)

            # Let dpkg only start daemons when desired
            scr = "#!/bin/sh\nexit 101\n"
            with open(policy, 'w') as f:
                f.write(scr)
            self.ec.run("chmod a+x '%s'" % policy)

            # Temporary fix ischroot
            if not exists(ischrootTmp):
                self.ec.run("mv '%s' '%s'" % (ischroot, ischrootTmp))
            if not exists(ischroot):
                self.ec.run("ln -s /bin/true '%s'" % ischroot)

            # HACK: create temporary script for chrooting
            silent_remove(terminal)
            scr = "#!/bin/sh\nchroot '%s' %s\n" % (self.rootPath, command)
            with open(terminal, 'w') as f:
                f.write(scr)
            self.ec.run("chmod a+x '%s'" % terminal)
            if exists("/usr/bin/xterm"):
                self.ec.run(
                    'export HOME=/root ; xterm -bg black -fg white -rightbar -title \"%s\" -e %s'
                    % (self.edition, terminal))
            elif self.ec.run('which x-terminal-emulator'):
                # use x-terminal-emulator if xterm isn't available
                self.ec.run('export HOME=/root ; x-terminal-emulator -e %s' %
                            terminal)
            else:
                print('Error: no valid terminal found')

            # restore wgetrc
            move(wgetrcBak, wgetrc)

            # move dns info
            if exists(resolveCnfBak):
                move(resolveCnfBak, resolveCnf)
            else:
                silent_remove(resolveCnf)

            # umount /proc /dev /dev/pts /sys
            self.unmount([pts, dev, proc, sys])

            # remove temp script
            silent_remove(terminal)

            # remove policy script
            silent_remove(policy)

            # replace ischroot
            if exists("%s.tmp" % ischroot):
                self.ec.run("rm '%s'" % ischroot)
                self.ec.run("mv '%s.tmp' '%s'" % (ischroot, ischroot))

            # cleanup /run
            self.ec.run("rm -rf '%s/run/'*" % self.rootPath)

        except Exception as detail:
            # restore wgetrc
            move(wgetrcBak, wgetrc)

            # move dns info
            if exists(resolveCnfBak):
                move(resolveCnfBak, resolveCnf)
            else:
                silent_remove(resolveCnf)

            # umount /proc /dev /dev/pts /sys
            self.unmount([pts, dev, proc, sys])

            # remove temp script
            silent_remove(terminal)

            # remove policy script
            silent_remove(policy)

            # replace ischroot
            if exists("%s.tmp" % ischroot):
                self.ec.run("rm '%s'" % ischroot)
                self.ec.run("mv '%s.tmp' '%s'" % (ischroot, ischroot))

            # cleanup /run
            self.ec.run("rm -rf '%s/run/'*" % self.rootPath)

            errText = 'Error launching terminal: '
            print((errText, detail))
Example #13
0
    def build_efi_image(self, distro_path):
        hostEfiArchitecture = getHostEfiArchitecture()
        if hostEfiArchitecture == "":
            return None

        # TODO - also 32-bit installs (haven't tested this)

        modules = "part_gpt part_msdos ntfs ntfscomp hfsplus fat ext2 chain boot configfile linux " \
                "multiboot iso9660 gfxmenu gfxterm loadenv efi_gop efi_uga loadbios fixvideo png " \
                "loopback search minicmd cat cpuid appleldr elf usb videotest " \
                "halt help ls reboot echo test normal sleep memdisk tar font video_fb video " \
                "gettext true video_bochs video_cirrus multiboot2 acpi gfxterm_background gfxterm_menu"

        rootPath = join(distro_path, "root")
        bootPath = join(distro_path, "boot")
        efiPath = join(distro_path, "EFI/BOOT")
        arch = getGuestEfiArchitecture(rootPath)

        grubEfiName = "bootx64"
        if arch != "x86_64":
            arch = "i386"
            grubEfiName = "bootia32"

        try:
            # Clean up old stuff and prepare for a new EFI image
            if not exists(efiPath):
                makedirs(efiPath)
            silent_remove(join(bootPath, "efi"))
            silent_remove(join(bootPath, "boot/memdisk"))
            silent_remove(join(bootPath, "boot/grub/x86_64-efi"))
            silent_remove(join(bootPath, "boot/grub/i386-efi"))
            silent_remove(join(bootPath, "boot/grub/efi.img"))
            silent_remove(join(bootPath, "boot/grub/loopback.cfg"))

            # Create embedded.cfg
            cont = """search --file --set=root /.trail
if [ -e ($root)/boot/grub/grub.cfg ]; then
  set prefix=($root)/boot/grub
  configfile $prefix/grub.cfg
else
  echo "Could not find /boot/grub/grub.cfg!"
fi
"""
            with open('embedded.cfg', 'w') as f:
                f.write(cont)

            # Create the .efi image with the embedded.cfg file
            self.ec.run("grub-mkimage "
                        "--config=embedded.cfg "
                        "-O {}-efi "
                        "-o '{}/{}.efi' "
                        "{}".format(arch, efiPath, grubEfiName, modules))

            print((">> Finished building EFI files"))
            return None

        except Exception as detail:
            return detail
Example #14
0
    def run(self):
        try:
            if not exists(self.mountDir):
                print(("Create mount directory: %s" % self.mountDir))
                makedirs(self.mountDir)

            rootDir = join(self.unpackDir, "root")
            if not exists(rootDir):
                print(("Create root directory: %s" % rootDir))
                makedirs(rootDir)

            isolinuxDir = join(self.unpackDir, "boot/isolinux")
            if not exists(isolinuxDir):
                print(("Create isolinux directory: %s" % isolinuxDir))
                makedirs(isolinuxDir)

            liveDir = join(self.unpackDir, "boot/live")
            if not exists(liveDir):
                print(("Create liveDir directory: %s" % liveDir))
                makedirs(liveDir)

            # Mount the ISO
            system("mount -o loop '%s' '%s'" % (self.unpackIso, self.mountDir))

            # Check isolinux directory
            mountIsolinux = join(self.mountDir, "isolinux")
            if not exists(mountIsolinux):
                self.ec.run("umount --force '%s'" % self.mountDir)
                self.returnMessage = "ERROR: Cannot find isolinux directory in ISO"

            fixCfgCmd = None
            dirs = []
            mountSquashfs = None
            if self.returnMessage is None:
                subdirs = self.getDirectSubDirectories(self.mountDir)
                for subdir in subdirs:
                    if self.hasSquashFs(join(self.mountDir, subdir)):
                        mountSquashfs = join(self.mountDir, subdir)
                        if subdir != "live":
                            fixCfgCmd = "sed -i 's/\/%s/\/live/g' '%s/isolinux.cfg'" % (
                                subdir, isolinuxDir)
                    elif subdir != "isolinux":
                        dirs.append(join(self.mountDir, subdir))

                if mountSquashfs is None:
                    self.ec.run("umount --force '%s'" % self.mountDir)
                    self.returnMessage = "ERROR: Cannot find squashfs directory in ISO"

            if self.returnMessage is None:
                # Copy files from ISO to unpack directory
                for d in dirs:
                    self.ec.run("rsync -at --del '%s' '%s'" %
                                (d, join(self.unpackDir, "boot/")))
                self.ec.run("rsync -at --del '%s/' '%s'" %
                            (mountIsolinux, isolinuxDir))
                self.ec.run("rsync -at --del '%s/' '%s'" %
                            (mountSquashfs, liveDir))
                self.ec.run("umount --force '%s'" % self.mountDir)

                if fixCfgCmd is not None:
                    self.ec.run(fixCfgCmd)

                # copy squashfs root
                squashfs = join(liveDir, "filesystem.squashfs")
                if exists(squashfs):
                    self.ec.run("mount -t squashfs -o loop '%s' '%s'" %
                                (squashfs, self.mountDir))
                    self.ec.run("rsync -at --del '%s/' '%s/'" %
                                (self.mountDir, rootDir))
                    self.ec.run("umount --force '%s'" % self.mountDir)

                # Cleanup
                silent_remove(self.mountDir, False)
                # set proper permissions
                self.ec.run("chmod 6755 '%s'" % join(rootDir, "usr/bin/sudo"))
                self.ec.run("chmod 0440 '%s'" % join(rootDir, "etc/sudoers"))

                self.returnMessage = "DONE - ISO unpacked to: %s" % self.unpackDir

            self.queue.put(self.returnMessage)

        except Exception as detail:
            self.ec.run("umount --force '%s'" % self.mountDir)
            silent_remove(self.mountDir, False)
            self.returnMessage = "ERROR: IsoUnpack: %(detail)s" % {
                "detail": detail
            }
            self.queue.put(self.returnMessage)
Example #15
0
    def run(self):
        try:
            if not exists(self.rootPath):
                self.returnMessage = "ERROR: Cannot find root directory: %s" % self.rootPath

            if not exists(self.bootPath):
                self.returnMessage = "ERROR: Cannot find boot directory: %s" % self.bootPath

            if self.returnMessage is None:
                print("======================================================")
                print("INFO: Cleanup and prepare ISO build...")
                print("======================================================")

                # Clean-up
                script = "cleanup.sh"
                scriptSource = join(self.scriptDir, "files/{}".format(script))
                scriptTarget = join(self.rootPath, script)
                if exists(scriptSource):
                    self.copy_file(scriptSource, scriptTarget)
                    self.ec.run("chmod a+x '%s'" % scriptTarget)
                    self.ed.openTerminal("/bin/bash '%s'" % script)
                    silent_remove(scriptTarget)

                rootHome = join(self.rootPath, "root")
                nanoHist = join(rootHome, ".nano_history")
                silent_remove(nanoHist)
                bashHist = join(rootHome, ".bash_history")
                silent_remove(bashHist)

                # Config naming
                regExp = "trail.*(\d{6}|-bit)"
                d = datetime.now()
                dateString = d.strftime("%Y%m")
                nameString = "{} {}".format(self.isoName, dateString)

                # write iso name to boot/isolinux/isolinux.cfg
                cfgFile = join(self.bootPath, "isolinux/isolinux.cfg")
                if exists(cfgFile):
                    content = ""
                    with open(cfgFile, 'r') as f:
                        content = f.read()
                    if content != "":
                        content = re.sub(regExp,
                                         nameString,
                                         content,
                                         flags=re.IGNORECASE)
                        # Make sure that the paths are correct (correcting very old stuff)
                        content = re.sub('.lz', '.img', content)
                        content = re.sub('/trail/', '/live/', content)
                        with open(cfgFile, 'w') as f:
                            f.write(content)

                # Write info for grub (EFI)
                grubFile = join(self.bootPath, "boot/grub/grub.cfg")
                if exists(grubFile):
                    content = ""
                    with open(grubFile, 'r') as f:
                        content = f.read()
                    if content != "":
                        content = re.sub(regExp,
                                         nameString,
                                         content,
                                         flags=re.IGNORECASE)
                        with open(grubFile, 'w') as f:
                            f.write(content)

                # Vmlinuz
                vmlinuzSymLink = join(self.distroPath, "root/vmlinuz")
                if lexists(vmlinuzSymLink):
                    vmlinuzFile = self.ec.run("ls -al '%s' | cut -d'>' -f2" %
                                              vmlinuzSymLink)[0].strip()
                else:
                    self.returnMessage = "ERROR: %s not found" % vmlinuzSymLink

            if self.returnMessage is None:
                vmlinuzPath = join(self.distroPath, "root/%s" % vmlinuzFile)
                if exists(vmlinuzPath):
                    print("Copy vmlinuz")
                    self.copy_file(vmlinuzPath, join(self.livePath, "vmlinuz"))
                else:
                    self.returnMessage = "ERROR: %s not found" % vmlinuzPath

            if self.returnMessage is None:
                # Initrd
                initrdSymLink = join(self.distroPath, "root/initrd.img")
                if lexists(initrdSymLink):
                    initrdFile = self.ec.run("ls -al '%s' | cut -d'>' -f2" %
                                             initrdSymLink)[0].strip()
                else:
                    self.returnMessage = "ERROR: %s not found" % initrdSymLink

            if self.returnMessage is None:
                initrdPath = join(self.distroPath, "root/%s" % initrdFile)
                if exists(initrdPath):
                    print("Copy initrd")
                    self.copy_file(initrdPath, join(self.livePath,
                                                    "initrd.img"))
                else:
                    self.returnMessage = "ERROR: %s not found" % initrdPath

            if self.returnMessage is None:
                print("======================================================")
                print("INFO: Start building ISO...")
                print("======================================================")

                # build squash root
                print("Creating SquashFS root...")
                print("Updating File lists...")
                dpkgQuery = ' dpkg -l | awk \'/^ii/ {print $2, $3}\' | sed -e \'s/ /\t/g\' '
                self.ec.run('chroot \"' + self.rootPath + '\"' + dpkgQuery +
                            ' > \"' +
                            join(self.livePath, "filesystem.packages") + '\"')

                # check for existing squashfs root
                print("Removing existing SquashFS root...")
                silent_remove(join(self.livePath, "filesystem.squashfs"))
                print("Building SquashFS root...")
                # check for custom mksquashfs (for multi-threading, new features, etc.)
                mksquashfs = self.ec.run(cmd="echo $MKSQUASHFS",
                                         returnAsList=False).strip()
                rootPath = join(self.distroPath, "root/")
                squashfsPath = join(self.livePath, "filesystem.squashfs")
                if mksquashfs == '' or mksquashfs == 'mksquashfs':
                    try:
                        nrprocessors = int(
                            int(self.ec.run("nproc", False, False)) / 2)
                        if nrprocessors < 1:
                            nrprocessors = 1
                    except:
                        nrprocessors = 1
                    cmd = "mksquashfs \"{}\" \"{}\" -comp xz -processors {}".format(
                        rootPath, squashfsPath, nrprocessors)
                else:
                    cmd = "{} \"{}\" \"{}\"".format(mksquashfs, rootPath,
                                                    squashfsPath)
                #print(cmd)
                self.ec.run(cmd)

                # Update isolinux files
                syslinuxPath = join(self.rootPath, "usr/lib/syslinux")
                modulesPath = join(syslinuxPath, "modules/bios")
                isolinuxPath = join(self.bootPath, "isolinux")
                self.ec.run("chmod -R +w '%s'" % isolinuxPath)
                cat = join(isolinuxPath, "boot.cat")
                silent_remove(cat)
                self.copy_file(join(modulesPath, "chain.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "hdt.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libmenu.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libgpl.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "reboot.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "vesamenu.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "poweroff.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "ldlinux.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libcom32.c32"), isolinuxPath)
                self.copy_file(join(modulesPath, "libutil.c32"), isolinuxPath)
                self.copy_file(join(self.rootPath, "boot/memtest86+.bin"),
                               join(isolinuxPath, "memtest86"))
                self.copy_file("/usr/lib/ISOLINUX/isolinux.bin", isolinuxPath)

                # Build the EFI image
                efi_error = self.build_efi_image(self.distroPath)
                if efi_error is not None:
                    self.returnMessage = "ERROR: BuildIso: %(efi_error)s" % {
                        "efi_error": efi_error
                    }

                # Create efiboot.img
                efiPath = join(self.distroPath, "EFI")
                efibootPath = join(isolinuxPath, "efiboot.img")
                print(("Create %s" % efibootPath))
                cmd = "rm '%s' 2>/dev/null;" \
                      "mkdosfs -F12 -n \"DEBIAN_EFI\" -C '%s' 2048;" \
                      "mcopy -s -i '%s' '%s' ::" % (efibootPath, efibootPath, efibootPath, efiPath)
                self.ec.run(cmd)

                # Check if the .trail file for Grub exists
                grubChkFile = join(self.bootPath, ".trail")
                if not exists(grubChkFile):
                    system("touch '%s'" % grubChkFile)

                # remove existing iso
                silent_remove(self.isoFileName)

                # build iso according to architecture
                print("Building ISO...")

                cmd = "xorriso -as mkisofs " \
                      "-r " \
                      "-volid '%s' " \
                      "-o '%s' " \
                      "-isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin " \
                      "-partition_offset 16 " \
                      "-J " \
                      "-l " \
                      "-joliet-long " \
                      "-c isolinux/boot.cat " \
                      "-b isolinux/isolinux.bin " \
                      "-no-emul-boot " \
                      "-boot-load-size 4 " \
                      "-boot-info-table " \
                      "-eltorito-alt-boot " \
                      "-e isolinux/efiboot.img " \
                      "-no-emul-boot " \
                      "-isohybrid-gpt-basdat " \
                      "'%s'" % (self.get_volid(self.isoName), self.isoFileName, self.bootPath)
                self.ec.run(cmd)

                print("Insert md5 in ISO")
                self.ec.run("implantisomd5 '%s'" % self.isoFileName)

                print("Create sha256 file...")
                oldmd5 = "%s.md5" % self.isoFileName
                silent_remove(oldmd5)
                self.ec.run(
                    "echo \"$(sha256sum \"%s\" | cut -d' ' -f 1)  %s\" > \"%s.sha256\""
                    % (self.isoFileName, self.isoBaseName, self.isoFileName))

                print("Create Torrent file...")
                torrentFile = "%s.torrent" % self.isoFileName
                silent_remove(torrentFile)
                self.ec.run(
                    "mktorrent -a \"%s\" -c \"%s\" -w \"%s\" -o \"%s\" \"%s\""
                    % (self.trackers, self.isoName, self.webseeds, torrentFile,
                       self.isoFileName))

                print("======================================================")
                if self.returnMessage is None:
                    self.returnMessage = "DONE - ISO Located at: %s" % self.isoFileName
                print((self.returnMessage))
                print("======================================================")

            self.queue.put(self.returnMessage)

        except Exception as detail:
            self.returnMessage = "ERROR: BuildIso: %(detail)s" % {
                "detail": detail
            }
            self.queue.put(self.returnMessage)