Esempio n. 1
0
    def __init__(self, pathDir, projectName):
        '''
        Constructor
        '''
        self.__repositoryPath = pathDir
        if not os.path.isdir(pathDir):
            os.makedirs(pathDir)
        self.__projectName = projectName
        self.__projectDir = os.path.join(self.__repositoryPath,
                                         self.__projectName)
        if not os.path.isdir(self.__projectDir):
            os.makedirs(self.__projectDir)

        self.__outOfDate = os.path.join(self.__projectDir, "outOfDate")

        self.__baseurl = None

        self.__createOptionDico = {}
        #       -u --baseurl <url>
        #              Optional base URL location for all files.
        if self.__baseurl != None:
            self.__createOptionDico["baseurl"] = "--baseurl " + self.__baseurl
        else:
            self.__createOptionDico["baseurl"] = ""

        self.__createOptionDico["path"] = self.__projectDir

        self.__mySubprocessCrt = SubprocessCrt()

        self.createRepo()
Esempio n. 2
0
def downloadFiles(rpmUrl):
    """Download several files with a common base URL"""
    cmd = "wget --continue --no-check-certificate %s -O %s"

    parseRes = urlparse.urlparse()
    mySubprocessCrt = SubprocessCrt()

    destPath = CACHEDIRECTORY + "/" + parseRes[1] + parseRes[2]

    mySubprocessCrt.execSubprocess(cmd % (rpmUrl, destPath))

    return destPath
Esempio n. 3
0
    def __init__(self, src, aChroot, dest=None, option=None):
        self.src = src
        self.root = os.path.abspath(os.path.expanduser(aChroot))
        self.option = option

        if not dest:
            dest = src
        self.dest = self.root + "/" + dest

        self.mounted = False
        self.mountcmd = findBinaryPath("mount")
        self.umountcmd = findBinaryPath("umount")

        self.__mySubprocessCrt = SubprocessCrt()
Esempio n. 4
0
    def __init__(self, workingDirectory):
        '''
        Constructor
        '''
        self.__repositoriesPath = ObsLightConfig.getRepositriesServerPath()
        self.__workingDirectory = workingDirectory
        pathDir = os.path.expanduser(self.__repositoriesPath)
        if not os.path.isdir(pathDir):
            os.makedirs(pathDir)

        self.__pathFile = os.path.join(self.__workingDirectory,
                                       "ObsLightRepositoriesConfig")

        self.__dicOBSLightRepositories = {}

        self.__mySubprocessCrt = SubprocessCrt()
Esempio n. 5
0
    def __init__(self):
        self.__isInit = False

        self.__chroot_lockfd = None
        self.__chroot_lock = ""

        self.__globalmounts = None
#        self.__qemu_emulator = None

        self.__chrootDirectory = None

        self.__mySubprocessCrt = SubprocessCrt()

        self.__obsLightPrint = ObsLightPrintManager.obsLightPrint

        self.__bindmounts = None
Esempio n. 6
0
def getLocalRepoServer():
    cmd = "/sbin/ifconfig"
    __mySubprocessCrt = SubprocessCrt()
    global HOST_IP
    localhostIp = "127.0.0.1"
    if HOST_IP is None:
        try:
            res = __mySubprocessCrt.execSubprocess(cmd, stdout=True, noOutPut=True)
            for ip in re.findall(".*inet.*?:([\d.]*)[\s]+.*", res):
                if isNonEmptyString(ip) and ip != localhostIp:
                    HOST_IP = ip
                    break
        except:
            HOST_IP = localhostIp
    if HOST_IP is None:
        HOST_IP = localhostIp
    return "http://%s:84" % HOST_IP
Esempio n. 7
0
    def __init__(self, name, workingDirectory, fromSave=None):
        # FIXME: there may be a better way to say it's not available
        if not micIsAvailable():
            from ObsLightErr import ObsLightNotImplementedError
            msg = "MIC is not installed on your system!\n"
            msg += "Install it and restart OBS Light."
            raise ObsLightNotImplementedError(msg)

        self.__mySubprocessCrt = SubprocessCrt()

        self.__kickstartPath = None
        self.__architecture = None
        self.__imageType = None
        self.__name = name
        self.__workingDirectory = os.path.join(workingDirectory, self.__name)
        self._ksManager = None

        if fromSave != None:
            if "architecture" in fromSave.keys():
                self.__architecture = fromSave["architecture"]
            if "imageType" in fromSave.keys():
                self.__imageType = fromSave["imageType"]
            if "name" in fromSave.keys():
                self.__name = fromSave["name"]
            if "workingDirectory" in fromSave.keys():
                self.__workingDirectory = fromSave["workingDirectory"]
            if "kickstartPath" in fromSave.keys():
                self.__kickstartPath = fromSave["kickstartPath"]

        pDir = self.projectDirectory
        if not os.path.isdir(pDir):
            os.makedirs(pDir)
        if not os.path.exists(self.localPackagesDirectory):
            os.makedirs(self.localPackagesDirectory)

        # If project has no Kickstart file, create an empty one
        if self.getKickstartFile() is None:
            # same name as the project
            ksPath = os.path.join(pDir, self.__name + ".ks")
            # file rights rw-r--r-- (644)
            rights = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
            # create the empty KS file
            os.mknod(ksPath, stat.S_IFREG | rights)
            self.setKickstartFile(ksPath)
Esempio n. 8
0
class ObsLightLocalServer(object):
    '''
    classdocs
    '''
    def __init__(self):
        '''
        Constructor
        '''
        self.__mySubprocessCrt = SubprocessCrt()
        self.__serverPath = ObsLightConfig.getImageServerPath()

    def __subprocess(self, command, command2=None, waitMess=False):
        '''
        
        '''
        if command2 != None:
            return self.__mySubprocessCrt.execPipeSubprocess(command=command,
                                                             command2=command2)

        return self.__mySubprocessCrt.execSubprocess(command=command,
                                                     waitMess=waitMess)

    def isObsLightServerAvailable(self):
        return os.path.isfile("/apache2/vhosts.d/obslight-image.conf")

    def addDirectoryToServer(self, directory):
        if os.path.isdir(directory):
            theBasename = os.path.basename(directory)
            projetPath = os.path.join(self.__serverPath, theBasename)
            command1 = "sudo mkdir " + projetPath
            command2 = "sudo mount --bind " + directory + " " + projetPath
            command31 = '''echo \'''' + projetPath + '''  *(rw,no_root_squash,nohide,insecure,no_subtree_check)\' '''
            command32 = '''sudo tee -a /etc/exports'''
            command4 = "sudo /usr/sbin/exportfs -ra"

            self.__subprocess(command=command1)
            self.__subprocess(command=command2)
            self.__subprocess(command=command31, command2=command32)
            self.__subprocess(command=command4)

            return 0
        else:
            raise ObsLightLocalServerErr("'" + directory +
                                         "' is not a directory.")
Esempio n. 9
0
def updateGitpackage(path):
    cmd = "git --git-dir=%s pull" % os.path.join(path, ".git")
    aSubprocessCrt = SubprocessCrt()
    return aSubprocessCrt.execSubprocess(cmd)
Esempio n. 10
0
class BindChrootMount:
    """Represents a bind mount of a directory into a chroot."""
    def __init__(self, src, aChroot, dest=None, option=None):
        self.src = src
        self.root = os.path.abspath(os.path.expanduser(aChroot))
        self.option = option

        if not dest:
            dest = src
        self.dest = self.root + "/" + dest

        self.mounted = False
        self.mountcmd = findBinaryPath("mount")
        self.umountcmd = findBinaryPath("umount")

        self.__mySubprocessCrt = SubprocessCrt()


    def __subprocess(self, command=None):
        return self.__mySubprocessCrt.execSubprocess(command=command)

    def ismounted(self):
        ret = False
        pathDest = os.path.abspath(self.dest)

        if not os.path.exists(pathDest):
                ret = False
                return ret

        dev_null = os.open("/dev/null", os.O_WRONLY)
        catcmd = findBinaryPath("cat")
        args = [ catcmd, "/proc/mounts" ]
        #TODO:change to use SubprocessCrt
        proc_mounts = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=dev_null)
        outputs = proc_mounts.communicate()[0].strip().split("\n")
        for line in outputs:
            pathMount = line.split()[1]

            if not os.path.exists(pathMount):
                continue

            if os.stat(pathMount).st_ino == os.stat(pathDest).st_ino:
                ret = True
                break

        os.close(dev_null)
        return ret

    def has_chroot_instance(self):
        lock = os.path.join(self.root, ".chroot.lock")
        try:
            return my_fuser(lock)
        # After reading my_fuser code, it seems that catching
        # "file not found" exception is equivalent to False.
        except IOError as e:
            msg = u"Got an exception while testing if chroot is in use: %s" % unicode(e)
            d = {'exception': e}
            ObsLightPrintManager.getLogger().error(msg, extra=d)
            return False

    def mount(self):
        if self.mounted or self.ismounted():
            return

        #imgcreate.makedirs(self.dest)
        command = "sudo mkdir -p " + self.dest
        self.__subprocess(command=command)
        command = "sudo " + self.mountcmd + " --bind " + self.src + " " + self.dest
        rc = self.__subprocess(command=command)
        if rc != 0:
            msg = "Bind-mounting '%s' to '%s' failed" % (self.src, self.dest)
            raise ObsLightErr.ObsLightChRootError(msg)
        if self.option:
            #TODO:change to use SubprocessCrt
            rc = subprocess.call(["sudo",
                                  self.mountcmd,
                                  "--bind",
                                  "-o",
                                  "remount,%s" % self.option,
                                  self.dest])
            if rc != 0:
                msg = "Bind-remounting '%s' failed with code %d" % (self.dest, rc)
                raise ObsLightErr.ObsLightChRootError(msg)
        self.mounted = True

    def unmount(self):
        if self.has_chroot_instance():
            return
        if self.ismounted():
            command = "sudo " + self.umountcmd + " -l " + self.dest
            self.__subprocess(command=command)
        self.mounted = False
Esempio n. 11
0
class ObsLightRepositories(object):
    '''
    classdocs
    '''
    def __init__(self, workingDirectory):
        '''
        Constructor
        '''
        self.__repositoriesPath = ObsLightConfig.getRepositriesServerPath()
        self.__workingDirectory = workingDirectory
        pathDir = os.path.expanduser(self.__repositoriesPath)
        if not os.path.isdir(pathDir):
            os.makedirs(pathDir)

        self.__pathFile = os.path.join(self.__workingDirectory,
                                       "ObsLightRepositoriesConfig")

        self.__dicOBSLightRepositories = {}

        self.__mySubprocessCrt = SubprocessCrt()

    def __subprocess(self, command=None, waitMess=False, stdout=False):
        return self.__mySubprocessCrt.execSubprocess(command=command,
                                                     waitMess=waitMess,
                                                     stdout=stdout)

    def getRepositoriesList(self):
        '''
        
        '''
        return self.__dicOBSLightRepositories.keys()

#    def __load(self, aFile=None):
#        '''
#
#        '''
#        return 0
#
#    def save(self):
#        '''
#
#        '''
#        aFile = open(pathFile, 'w')
#        pickle.dump(saveconfigProject, aFile)
#        aFile.close()
#        return 0

    def scanRepository(self):
        for projectName in os.listdir(self.__repositoriesPath):
            self.createRepo(projectName)

    def getRepository(self, projectName):
        pathDir = os.path.join(self.__repositoriesPath,
                               self.__repositoriesPath)

        if projectName in self.__dicOBSLightRepositories.keys():
            return self.__dicOBSLightRepositories[projectName]

        self.createRepository(projectName)
        return self.__dicOBSLightRepositories[projectName]

    def createRepository(self, projectName):
        if projectName in self.__dicOBSLightRepositories.keys():
            return 0
        repository = ObsLightRepository(self.__repositoriesPath, projectName)
        self.__dicOBSLightRepositories[projectName] = repository
        return 0

    def deleteRepository(self, projectName):
        if projectName in self.getRepositoriesList():
            res = self.__dicOBSLightRepositories[projectName].deleteRepository(
            )
            del self.__dicOBSLightRepositories[projectName]
            return res
        return 0

    def createRepo(self, projectName):
        if projectName in self.getRepositoriesList():
            return self.__dicOBSLightRepositories[projectName].createRepo()
        return 0
Esempio n. 12
0
class ObsLightRepository(object):
    '''
    classdocs
    '''
    def __init__(self, pathDir, projectName):
        '''
        Constructor
        '''
        self.__repositoryPath = pathDir
        if not os.path.isdir(pathDir):
            os.makedirs(pathDir)
        self.__projectName = projectName
        self.__projectDir = os.path.join(self.__repositoryPath,
                                         self.__projectName)
        if not os.path.isdir(self.__projectDir):
            os.makedirs(self.__projectDir)

        self.__outOfDate = os.path.join(self.__projectDir, "outOfDate")

        self.__baseurl = None

        self.__createOptionDico = {}
        #       -u --baseurl <url>
        #              Optional base URL location for all files.
        if self.__baseurl != None:
            self.__createOptionDico["baseurl"] = "--baseurl " + self.__baseurl
        else:
            self.__createOptionDico["baseurl"] = ""

        self.__createOptionDico["path"] = self.__projectDir

        self.__mySubprocessCrt = SubprocessCrt()

        self.createRepo()

    def __subprocess(self, command=None, waitMess=False, stdout=False):
        return self.__mySubprocessCrt.execSubprocess(command=command,
                                                     waitMess=waitMess,
                                                     stdout=stdout)

    def addRPM(self, absBuildRootpath, listRPM):
        needTouch = False
        for rpm in listRPM:
            srcPath = os.path.join(absBuildRootpath, rpm)
            dstPath = os.path.join(self.__projectDir, rpm)
            if os.path.isfile(srcPath):
                dstDir = os.path.dirname(dstPath)
                if os.path.isfile(srcPath) and srcPath.endswith(".rpm"):
                    if not os.path.isdir(dstDir):
                        os.makedirs(dstDir)

                shutil.copyfile(srcPath, dstPath)

                needTouch = True
        if needTouch:
            self.touch()

    def removeRPM(self, listRPM):
        needTouch = False

        for rpm in listRPM:
            rpmPath = os.path.join(self.__projectDir, rpm)

            if os.path.isfile(rpmPath):
                os.unlink(rpmPath)
                needTouch = True
        if needTouch:
            self.touch()

    def touch(self):
        with file(self.__outOfDate, 'a'):
            os.utime(self.__outOfDate, None)

    def removeTouch(self):
        if os.path.isfile(self.__outOfDate):
            os.unlink(self.__outOfDate)

    def createRepo(self):
        #       --update
        #              If  metadata already exists in the outputdir and an rpm is unchanged (based on file size and mtime) since the metadata was generated, reuse the existing metadata
        #              rather than recalculating it. In the case of a large repository with only a few new or modified rpms this can significantly reduce I/O and processing time.
        command = "createrepo --update %(baseurl)s %(path)s"
        command = command % self.__createOptionDico

        res = self.__subprocess(command=command)
        self.removeTouch()
        return res

    def isOutOfDate(self):
        if os.path.isfile(self.__outOfDate):
            return True
        else:
            return False

    def deleteRepository(self):
        command = "rm -r %(path)s"
        command = command % self.__createOptionDico
        return self.__subprocess(command=command)

    def getLocalRepository(self):
        return ObsLightConfig.getLocalRepoServer() + "/" + self.__projectName
Esempio n. 13
0
    def __init__(self, projectChroot):
        self.__chroot = projectChroot
        self.__mySubprocessCrt = SubprocessCrt()

        self.__zyppLock = "/var/run/zypp.pid"
Esempio n. 14
0
class ObsLightRepoManager(object):
    '''
    class Git management
    '''

    def __init__(self, projectChroot):
        self.__chroot = projectChroot
        self.__mySubprocessCrt = SubprocessCrt()

        self.__zyppLock = "/var/run/zypp.pid"

    def testZypperAvailable(self):
        if os.path.exists(self.__zyppLock):
            try:
                with open(self.__zyppLock, "r") as pidFile:
                    pid = pidFile.readline()[:-1]
            except :# pylint: disable-msg=W0702
                return 0
            if os.path.exists("/proc/%s/comm" % (pid)):
                try:
                    with open("/proc/%s/comm" % (pid), "r") as pidFile:
                        programmeName = pidFile.readline()[:-1]
                except:# pylint: disable-msg=W0702
                    return 0

                if "packagekitd" == programmeName:
                    print "programmeName", programmeName, "packagekitd" == programmeName
                    self.__subprocess("sudo pkill packagekitd")
                    return 0
                msg = "%s (pid:%s) lock obslight zypper command" % (programmeName, pid)
                raise ObsLightErr.ObsLightChRootError(msg)
            return 0
        return 0

    def __subprocess(self, command=None, stdout=False, noOutPut=False):
        return self.__mySubprocessCrt.execSubprocess(command, stdout=stdout, noOutPut=noOutPut)

    def __listSubprocess(self, command=None):
        for c in command:
            res = self.__mySubprocessCrt.execSubprocess(c)
        return res

    def __getZypperCommand(self):
        command = "sudo zypper --cache-dir %s --root %s"
        command = command % ("/var/cache/zypp", self.__chroot.getDirectory())
        return command

    def addRepo(self, repos=None, alias=None):
        self.testZypperAvailable()
        command = []
        command.append("%s ar %s '%s'" % (self.__getZypperCommand(), repos, alias))
        command.append("%s --no-gpg-checks --gpg-auto-import-keys ref" % (self.__getZypperCommand()))
        return self.__listSubprocess(command=command)

    def deleteRepo(self, repoAlias):
        self.testZypperAvailable()
        command = []
        command.append("%s rr %s " % (self.__getZypperCommand(), repoAlias))
        command.append("%s --no-gpg-checks --gpg-auto-import-keys ref" % (self.__getZypperCommand()))
        self.__listSubprocess(command=command)

    def installBuildRequires(self, packageName, dicoPackageBuildRequires, arch):
        self.testZypperAvailable()
        if len(dicoPackageBuildRequires.keys()) == 0:
            return 0

        #command = []
#        command.append("%s --no-gpg-checks --gpg-auto-import-keys ref" % (self.__getZypperCommand()))
#        cmd = "%s --non-interactive in --force-resolution " % (self.__getZypperCommand())
#        cmd = ""
#        for pk in listPackageBuildRequires:
#            if pk.count("-") >= 2:
#                lastMinus = pk.rfind("-")
#                cutMinus = pk.rfind("-", 0, lastMinus)
#                # OBS sometimes returns "future" build numbers, and dependency
#                # resolution fails. So with forget build number.
#                name = pk[:cutMinus]
#
#                #pkCmd = '"' + name + ">=" + pk[cutMinus + 1:lastMinus] + '"'
#                pkCmd = name
#            else:
#                pkCmd = pk
#            cmd += " " + pkCmd

        aFile = tempfile.NamedTemporaryFile("w", delete=False)
        pickle.dump(dicoPackageBuildRequires, aFile)
        aFile.flush()
        aFile.close()

        #command.append(cmd )
        print "sudo obsMicInstall %s %s %s " % (self.__chroot.getDirectory() ,
                                                arch,
                                                aFile.name)
        res = self.__subprocess("sudo obsMicInstall %s %s %s " % (self.__chroot.getDirectory() ,
                                                                  arch,
                                                                  aFile.name))
        #res = self.__listSubprocess(command=command)

        if res != 0:
            msg = "The installation of some dependencies of '%s' failed\n" % packageName
            msg += "Maybe a repository is missing."
            raise ObsLightErr.ObsLightChRootError(msg)

        return res
Esempio n. 15
0
 def __init__(self, projectChroot):
     ObsLightObject.__init__(self)
     self.__chroot = projectChroot
     self.__mySubprocessCrt = SubprocessCrt()
     self.initialTag = "initial-prep"
Esempio n. 16
0
class ObsLightMic(object):

    def __init__(self):
        self.__isInit = False

        self.__chroot_lockfd = None
        self.__chroot_lock = ""

        self.__globalmounts = None
#        self.__qemu_emulator = None

        self.__chrootDirectory = None

        self.__mySubprocessCrt = SubprocessCrt()

        self.__obsLightPrint = ObsLightPrintManager.obsLightPrint

        self.__bindmounts = None

    def destroy(self):
        if self.__isInit == True:
            self.cleanup_chrootenv(bindmounts=self.__bindmounts)
        self.__isInit = False
#        dev_null = os.open("/dev/null", os.O_WRONLY)
#        proc_mounts = subprocess.Popen([ 'cat', "/proc/mounts" ], stdout=subprocess.PIPE, stderr=dev_null)
#        outputs = proc_mounts.communicate()[0].strip().split("\n")
#        for line in outputs:
#            if line.find(os.path.abspath(self.__chrootDirectory)) >= 0:
#                if os.path.abspath(self.__chrootDirectory) == line.split()[1]:
#                    continue
#                point = line.split()[1]
#                ret = subprocess.call([ "umount", "-l", point ], stdout=dev_null, stderr=dev_null)
#                if ret != 0:
#                    print "ERROR: failed to unmount %s" % point
#                    os.close(dev_null)
#                    return ret
#        os.close(dev_null)"""

    def isInit(self):
        return self.__isInit

    def initChroot(self, chrootDirectory=None, mountDir=None):
        mountDir = mountDir or {}
        self.testOwnerChRoot(path=chrootDirectory)
        self.__bindmounts = ""
        for k in mountDir.keys():
            self.__bindmounts += mountDir[k] + ":" + k + ";"
        self.__chrootDirectory = chrootDirectory
#        self.__findArch()

        self.setup_chrootenv(bindmounts=self.__bindmounts)

        self.__isInit = True

    def testOwnerChRoot(self, path):
        if os.path.isdir(path):
            if os.stat(path).st_uid != 0:
                message = "The project file system '%s' is not owned by root." % path
                raise ObsLightErr.ObsLightChRootError(message)
        else:
            message = "Can't test owner of the project file system, "
            message += "the directory '%s' does not exist." % path
            raise ObsLightErr.ObsLightChRootError(message)

    def __subprocess(self, command=None):
        return self.__mySubprocessCrt.execSubprocess(command=command)

    def setup_chrootenv(self, bindmounts=None):
        def get_bind_mounts(chrootdir, bindmounts):
            chrootmounts = []
            if bindmounts in ("", None):
                bindmounts = ""
            mounts = bindmounts.split(";")
            for mount in mounts:
                if mount == "":
                    continue
                srcdst = mount.split(":")
                srcdst[0] = os.path.abspath(os.path.expanduser(srcdst[0]))
                if len(srcdst) == 1:
                    srcdst.append("none")
                if not os.path.isdir(srcdst[0]):
                    continue
                if srcdst[0] in ("/proc",
                                 "/proc/sys/fs/binfmt_misc",
                                 "/",
                                 "/sys",
                                 "/dev",
                                 "/dev/pts",
                                 "/dev/shm",
                                 "/var/lib/dbus",
                                  "/var/run/dbus"):
                    #chroot.pwarning("%s will be mounted by default." % srcdst[0])
                    message = "%s will be mounted by default." % srcdst[0]
                    self.__obsLightPrint(message, isDebug=True)
                    continue
                if srcdst[1] == "" or srcdst[1] == "none":
                    srcdst[1] = None
                else:
                    srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
                    #if os.path.isdir(chrootdir + "/" + srcdst[1]):
                    #    #chroot.pwarning("%s has existed in %s , skip it." % (srcdst[1], chrootdir))
                    #    self.__obsLightPrint("%s has existed in %s , skip it." % (srcdst[1], chrootdir) , isDebug=True)
                    #    continue
                # "dirsync" option added to try to avoid random bug which made scripts
                # written by obslight in chrootTransfer not available from chroot jail
                chrootmounts.append(BindChrootMount(srcdst[0], chrootdir, srcdst[1], "dirsync"))

            #"""Default bind mounts"""
            chrootmounts.append(BindChrootMount("/proc", chrootdir, None))
            chrootmounts.append(BindChrootMount("/proc/sys/fs/binfmt_misc",
                                                self.__chrootDirectory,
                                                None))
            chrootmounts.append(BindChrootMount("/sys", chrootdir, None))
            chrootmounts.append(BindChrootMount("/dev", chrootdir, None))
            chrootmounts.append(BindChrootMount("/dev/pts", chrootdir, None))
            chrootmounts.append(BindChrootMount("/var/lib/dbus", chrootdir, None))
            chrootmounts.append(BindChrootMount("/var/run/dbus", chrootdir, None))

            # FIXME: is this needed ? It makes %prep of kmod-virtiogl fail.
#            for kernel in os.listdir("/lib/modules"):
#                chrootmounts.append(BindChrootMount("/lib/modules/" + kernel, chrootdir, None, "ro"))

            self.__globalmounts = chrootmounts

        def bind_mount(chrootmounts):
            for b in chrootmounts:
                self.__obsLightPrint("bind_mount: %s -> %s" % (b.src, b.dest), isDebug=True)
                b.mount()
                # b.mount() should raise an exception if it fails
                # so b.ismounted() is supposed to be always True at this point
                assert b.ismounted(), "Error while mounting %s" % b.src

        def setup_resolv(chrootdir):
            command = "sudo cp /etc/resolv.conf " + chrootdir + "/etc/resolv.conf"
            self.__subprocess(command=command)

        get_bind_mounts(self.__chrootDirectory, bindmounts)
        bind_mount(self.__globalmounts)
        setup_resolv(self.__chrootDirectory)
        mtab = "/etc/mtab"
        dstmtab = self.__chrootDirectory + mtab
        if not os.path.islink(dstmtab):
            command = "sudo cp " + mtab + " " + dstmtab
            self.__subprocess(command=command)
        self.__chroot_lock = os.path.join(self.__chrootDirectory, ".chroot.lock")
        self.__chroot_lockfd = open(self.__chroot_lock, "w")
        return self.__globalmounts

    def cleanup_chrootenv(self, bindmounts=None):

        def bind_unmount(chrootmounts):
            chrootmounts.reverse()
            for b in chrootmounts:
                self.__obsLightPrint("bind_unmount: %s -> %s" % (b.src, b.dest), isDebug=True)
                b.unmount()

        #def cleanup_resolv(chrootdir):
        #    fd = open(chrootdir + "/etc/resolv.conf", "w")
        #    fd.truncate(0)
        #    fd.close()

        def kill_processes(chrootdir):
            for procfile in glob.glob("/proc/*/root"):
                try:
                    if os.readlink(procfile) == chrootdir:
                        pid = int(procfile.split("/")[2])
                        os.kill(pid, 9)
                except BaseException:
                    return None
        self.__chroot_lockfd.close()

        bind_unmount(self.__globalmounts)
        if not my_fuser(self.__chroot_lock):
            #cleanup_resolv(self.__chrootDirectory)
            self.__subprocess(command="sudo rm " + self.__chrootDirectory + "/etc/resolv.conf")
            self.__subprocess(command="sudo touch " + self.__chrootDirectory + "/etc/resolv.conf")

            if os.path.exists(self.__chrootDirectory + "/etc/mtab"):
                command = "sudo rm " + self.__chrootDirectory + "/etc/mtab"
                self.__subprocess(command=command)

            kill_processes(self.__chrootDirectory)

        self.cleanup_mountdir(self.__chrootDirectory, bindmounts)
#        if self.__qemu_emulator:
#
#            command = "sudo rm " + self.__chrootDirectory + self.__qemu_emulator
#            self.__subprocess(command=command)

        command = "sudo rm " + self.__chroot_lock
        self.__subprocess(command=command)

    def cleanup_mountdir(self, chrootdir, bindmounts):
        if bindmounts == "" or bindmounts == None:
            return
        mounts = bindmounts.split(";")
        for mount in mounts:
            if mount == "":
                continue
            srcdst = mount.split(":")
            if len(srcdst) == 1:
                srcdst.append("none")
            if srcdst[1] == "" or srcdst[1] == "none":
                srcdst[1] = srcdst[0]
            srcdst[1] = os.path.abspath(os.path.expanduser(srcdst[1]))
            tmpdir = chrootdir + "/" + srcdst[1]
            if os.path.isdir(tmpdir):
                if len(os.listdir(tmpdir)) == 0:
                    #shutil.rmtree(tmpdir, ignore_errors = True)
                    command = "sudo rm -r " + tmpdir
                    self.__subprocess(command=command)
                else:
                    self.__obsLightPrint("dir %s isn't empty." % tmpdir, isDebug=True)
                    #chroot.pwarning("dir %s isn't empty." % tmpdir)

    def chroot(self, bindmounts=None, execute="/bin/bash"):
        def mychroot():
            os.chroot(self.__chrootDirectory)
            os.chdir("/")

        try:
            self.__obsLightPrint("Launching shell. Exit to continue.", isDebug=True)
            self.__obsLightPrint("----------------------------------", isDebug=True)
            self.setup_chrootenv(bindmounts)

            args = shlex.split(execute)

            subprocess.call(args, preexec_fn=mychroot)

        except OSError, Err:
            (errCode, msg) = Err
            self.__obsLightPrint(errCode, isDebug=True)
            raise OSError(errCode, "Failed to chroot: %s" % msg)
        finally:
Esempio n. 17
0
def cloneGitpackage(url, path):
    cmd = "git clone %s %s" % (url, path)
    aSubprocessCrt = SubprocessCrt()
    return aSubprocessCrt.execSubprocess(cmd)
Esempio n. 18
0
class ObsLightGitManager(ObsLightObject):
    '''
    Manage the internal Git repository used to generate patches on packages.
    '''
    def __init__(self, projectChroot):
        ObsLightObject.__init__(self)
        self.__chroot = projectChroot
        self.__mySubprocessCrt = SubprocessCrt()
        self.initialTag = "initial-prep"

    def __subprocess(self, command=None, stdout=False, noOutPut=False):
        return self.__mySubprocessCrt.execSubprocess(command,
                                                     stdout=stdout,
                                                     noOutPut=noOutPut)

    def __listSubprocess(self, command=None):
        for c in command:
            res = self.__mySubprocessCrt.execSubprocess(c)
        return res

    def ___execPipeSubprocess(self, command, command2):
        return self.__mySubprocessCrt.execPipeSubprocess(command, command2)

    def prepareGitCommand(self, workTree, subcommand, gitDir):
        """
        Construct a Git command-line, setting its working tree to `workTree`,
        and git directory to `gitDir`, and then appends `subcommand`.
        Output example:
          git --git-dir=<gitDir> --work-tree=<workTree> <subcommand>
        """
        absWorkTree = self.__chroot.getDirectory() + workTree
        absGitDir = self.__chroot.getDirectory() + gitDir
        command = "git --git-dir=%s --work-tree=%s " % (absGitDir, absWorkTree)
        command += subcommand
        return command

    def makeArchiveGitSubcommand(self,
                                 prefix,
                                 revision=u"HEAD",
                                 outputFilePath=None):
        """
        Construct a Git 'archive' subcommand with auto-detected format.
        If outputFilePath is None, format will be tar, and output will
        be stdout.
        """
        command = "archive --prefix=%s/ %s "
        command = command % (prefix, revision)
        if outputFilePath is not None:
            command += " -o %s" % outputFilePath
        return command

    def checkGitUserConfig(self, workTree, gitDir):
        """
        Git complains if you don't set 'user.name' and 'user.email' config
        parameters. This method checks if they are set, and in case they
        aren't, set them.
        """
        confParams = {
            "user.email": "*****@*****.**",
            "user.name": "OBS Light"
        }
        for param, value in confParams.iteritems():
            cmd = self.prepareGitCommand(workTree, "config " + param, gitDir)
            res = self.__subprocess(cmd, stdout=True, noOutPut=True)
            self.logger.debug("Git parameter '%s': '%s'" % (param, res))
            if not isNonEmptyString(res):
                self.logger.debug(" -> Setting it to '%s'" % (value))
                cmd2 = self.prepareGitCommand(
                    workTree, 'config %s "%s"' % (param, value), gitDir)
                res2 = self.__subprocess(cmd2)
                if res2 != 0:
                    msg = 'Failed to set git parameter "%s", next git operation may fail!'
                    self.logger.warning(msg % param)

    def execMakeArchiveGitSubcommand(self, packagePath, outputFilePath, prefix,
                                     packageCurrentGitDirectory):
        absOutputFilePath = self.__chroot.getDirectory()
        # TODO: make something more generic (gz, bz2, xz...)
        if outputFilePath.endswith(".tar.gz"):
            # git archive does not know .tar.gz,
            # we have to compress the file afterwards
            absOutputFilePath += outputFilePath[:-len('.gz')]
        else:
            absOutputFilePath += outputFilePath
        archiveSubCommand = self.makeArchiveGitSubcommand(
            prefix, outputFilePath=absOutputFilePath)
        command = self.prepareGitCommand(packagePath, archiveSubCommand,
                                         packageCurrentGitDirectory)
        res = self.__subprocess(command)
        if res != 0:
            return res
        if outputFilePath.endswith(".tar.gz"):
            # Without '-f' user will be prompted if .gz file already exists
            command = "gzip -f %s" % absOutputFilePath
            res = self.__subprocess(command)
        return res

    def findEmptyDirectory(self, package):
        # git ignores empty directories so we must save them into a file.
        projectPath = self.__chroot.getDirectory(
        ) + package.getChrootBuildDirectory()
        res = []
        for root, dirs, files in os.walk(projectPath):
            if len(dirs) == 0 and len(files) == 0:
                res.append(root.replace(projectPath + "/", ""))

        # TODO: move this file to BUILD/
        with open(projectPath + "/.emptyDirectory", 'w') as f:
            for d in res:
                f.write(d + "\n")

    def initGitWatch(self, path, package):
        '''
        Initialize a Git repository in the specified path, and 'git add' everything.
        '''
        if path is None:
            raise ObsLightErr.ObsLightChRootError(
                "Path is not defined in initGitWatch.")

        absPath = self.__chroot.getDirectory() + path

        pkgCurGitDir = package.getCurrentGitDirectory()
        # Ensure we have access rights on the directory
        res = self.__chroot.allowAccessToObslightGroup(
            os.path.dirname(pkgCurGitDir), absolutePath=False)

        self.findEmptyDirectory(package)

        timeString = time.strftime("%Y-%m-%d_%Hh%Mm%Ss")
        comment = '\"auto commit first commit %s\"' % timeString

        # Create .gitignore file.
        self.initGitignore(path, package)

        if res != 0:
            msg = "Failed to give access rights on '%s'. Git repository creation may fail."
            self.logger.warn(msg % os.path.dirname(pkgCurGitDir))

        res = self.__subprocess(
            self.prepareGitCommand(path, "init ", pkgCurGitDir))
        if res != 0:
            msg = "Creation of the git repository for %s failed. See the log for more information."
            raise ObsLightErr.ObsLightChRootError(msg % package.getName())
        self.checkGitUserConfig(path, pkgCurGitDir)

        command = []
        command.append(
            self.prepareGitCommand(path, "add " + absPath + "/\*",
                                   pkgCurGitDir))
        command.append(
            self.prepareGitCommand(path, "commit -a -m %s" % comment,
                                   pkgCurGitDir))
        command.append(
            self.prepareGitCommand(path, "tag %s" % self.initialTag,
                                   pkgCurGitDir))

        res = self.__listSubprocess(command=command)
        if res != 0:
            msg = "Initialization of the git repository for %s failed. "
            msg += "See the log for more information."
            raise ObsLightErr.ObsLightChRootError(msg % package.getName())

    def resetToPrep(self, path, package):
        pkgCurGitDir = package.getCurrentGitDirectory()
        res = self.__listSubprocess([
            self.prepareGitCommand(path, "checkout  %s" % self.initialTag,
                                   pkgCurGitDir)
        ])
        return res

    def initGitignore(self, path, package):
        absPath = self.__chroot.getDirectory() + path
        with open(absPath + "/.gitignore", 'a') as f:
            f.write("debugfiles.list\n")
            f.write("debuglinks.list\n")
            f.write("debugsources.list\n")
            f.write(".gitignore\n")


#            f.write("*.in\n")

    def ignoreGitWatch(self,
                       package,
                       path=None,
                       commitComment="first build commit"):
        '''
        Add all Git untracked files of `path` to .gitignore
        and commit.
        '''

        if path is None:
            raise ObsLightErr.ObsLightChRootError(
                "path is not defined in initGitWatch.")

        absPath = self.__chroot.getDirectory() + path

        timeString = time.strftime("%Y-%m-%d_%Hh%Mm%Ss")
        comment = '\"auto commit %s %s\"' % (commitComment, timeString)

        command = self.prepareGitCommand(path, u"status -u -s ",
                                         package.getCurrentGitDirectory())
        #| sed -e 's/^[ \t]*//' " + u"| cut -d' ' -f2 >> %s/.gitignore" % absPath, package.getCurrentGitDirectory()

        res = self.__subprocess(command=command, stdout=True)
        # some packages modify their file rights, so we have to ensure
        # this file is writable
        self.__subprocess("sudo chmod -f a+w %s %s/.gitignore" %
                          (absPath, absPath))

        with open(absPath + "/.gitignore", 'a') as f:
            if type(res) is not type(int()):
                for line in res.split("\n"):
                    if len(line) > 0:
                        line = " ".join(line.strip(" ").split(" ")[1:])
                        f.write(line + "\n")

        return self.__subprocess(
            self.prepareGitCommand(path, u"commit -a -m %s" % comment,
                                   package.getCurrentGitDirectory()))

    def getCommitTag(self, path, package):
        '''
        Get the last Git commit hash.
        '''
        command = self.prepareGitCommand(path,
                                         " log HEAD --pretty=short -n 1 ",
                                         package.getCurrentGitDirectory())

        result = self.__subprocess(command=command, stdout=True)

        for line in result.split("\n"):
            if line.startswith("commit "):
                res = line.strip("commit").strip().rstrip("\n")
                return res

    def getListCommitTag(self, path, package):
        return self.getCommitTagList(path, package)

    def getCommitTagList(self, path, package):
        '''
        Get the last Git commit hash.
        '''
        command = self.prepareGitCommand(path,
                                         " log HEAD --pretty=short -n 20 ",
                                         package.getCurrentGitDirectory())

        result_tmp = self.__subprocess(command=command, stdout=True)
        result = []
        for line in result_tmp.split("\n"):
            if line.startswith("commit "):
                res = line.strip("commit ").rstrip("\n")
                result.append((res, "Comment"))
        return result

    def commitGit(self, mess, package):
        packagePath = package.getChrootBuildDirectory()
        command = []
        if packagePath is None:
            raise ObsLightErr.ObsLightChRootError(
                "path is not defined in commitGit for .")

        timeString = time.strftime("%Y-%m-%d_%Hh%Mm%Ss")
        comment = '\"auto commit %s %s\"' % (mess, timeString)

        path = self.__chroot.getDirectory() + packagePath
        command.append(
            self.prepareGitCommand(packagePath, " add %s/\* " % (path),
                                   package.getCurrentGitDirectory()))
        command.append(
            self.prepareGitCommand(packagePath, " commit -a -m %s" % comment,
                                   package.getCurrentGitDirectory()))
        self.__listSubprocess(command=command)

        tag2 = self.getCommitTag(packagePath, package)
        package.setSecondCommit(tag2)

    def createPatch(self, package, packagePath, tag1, tag2, patch):
        command = self.prepareGitCommand(
            packagePath, "diff -p -a --binary %s %s " % (tag1, tag2),
            package.getCurrentGitDirectory())
        res = self.__subprocess(command=command, stdout=True)

        pathPackagePackaging = package.getPackagingDirectiory()

        with open(pathPackagePackaging + "/" + patch, "w'") as f:
            f.write(res)
        return 0
Esempio n. 19
0
 def __init__(self):
     '''
     Constructor
     '''
     self.__mySubprocessCrt = SubprocessCrt()
     self.__serverPath = ObsLightConfig.getImageServerPath()
Esempio n. 20
0
def commitGitpackage(path, message):
    cmd = "git --work-tree=%s --git-dir=%s commit -a -m \"%s\"" % (
        path, os.path.join(path, ".git"), message)
    aSubprocessCrt = SubprocessCrt()
    return aSubprocessCrt.execSubprocess(cmd)
Esempio n. 21
0
class ObsLightMicProject(object):

    LocalPackagesDirectoryName = "localPackages"
    ObsLightUserGroup = "users"

    def __init__(self, name, workingDirectory, fromSave=None):
        # FIXME: there may be a better way to say it's not available
        if not micIsAvailable():
            from ObsLightErr import ObsLightNotImplementedError
            msg = "MIC is not installed on your system!\n"
            msg += "Install it and restart OBS Light."
            raise ObsLightNotImplementedError(msg)

        self.__mySubprocessCrt = SubprocessCrt()

        self.__kickstartPath = None
        self.__architecture = None
        self.__imageType = None
        self.__name = name
        self.__workingDirectory = os.path.join(workingDirectory, self.__name)
        self._ksManager = None

        if fromSave != None:
            if "architecture" in fromSave.keys():
                self.__architecture = fromSave["architecture"]
            if "imageType" in fromSave.keys():
                self.__imageType = fromSave["imageType"]
            if "name" in fromSave.keys():
                self.__name = fromSave["name"]
            if "workingDirectory" in fromSave.keys():
                self.__workingDirectory = fromSave["workingDirectory"]
            if "kickstartPath" in fromSave.keys():
                self.__kickstartPath = fromSave["kickstartPath"]

        pDir = self.projectDirectory
        if not os.path.isdir(pDir):
            os.makedirs(pDir)
        if not os.path.exists(self.localPackagesDirectory):
            os.makedirs(self.localPackagesDirectory)

        # If project has no Kickstart file, create an empty one
        if self.getKickstartFile() is None:
            # same name as the project
            ksPath = os.path.join(pDir, self.__name + ".ks")
            # file rights rw-r--r-- (644)
            rights = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
            # create the empty KS file
            os.mknod(ksPath, stat.S_IFREG | rights)
            self.setKickstartFile(ksPath)

    def __subprocess(self, command):
        return self.__mySubprocessCrt.execSubprocess(command)

    def __loadKsManager(self):
        self._ksManager = ObsLightKickstartManager(self.getKickstartFile())

    @property
    def kickstartManager(self):
        if self._ksManager is None:
            self.__loadKsManager()
        return self._ksManager

    @property
    def projectDirectory(self):
        """
        Get the project working directory.
        """
        return self.__workingDirectory

    @property
    def localPackagesDirectory(self):
        """Get the directory where local RPMs are stored"""
        return os.path.join(self.projectDirectory, self.LocalPackagesDirectoryName)

    def getDic(self):
        aDic = {}
        aDic["kickstartPath"] = self.__kickstartPath
        aDic["architecture"] = self.__architecture
        aDic["imageType"] = self.__imageType
        aDic["name"] = self.__name
        aDic["workingDirectory"] = self.__workingDirectory
        return aDic

    def failIsUserNotInUserGroup(self):
        """
        Raise an exception if the user running this program is not member
        of the user group defined by OBS Light (self.ObsLightUserGroup).
        This is required for the custom sudo rules to apply.
        """
        if not isUserInGroup(self.ObsLightUserGroup):
            message = "You are not in the '%s' group. " % self.ObsLightUserGroup
            message += "Please add yourself in this group:\n"
            message += "  sudo usermod -a -G %s `whoami`\n" % self.ObsLightUserGroup
            message += "then logout and login again."
            raise ObsLightErr.ObsLightMicProjectErr(message)

# --- Kickstart management ---------------------------------------------------
    def setKickstartFile(self, filePath):
        """
        Set the kickstart file of this project.
        """
        if not os.path.isfile(filePath):
            raise ObsLightErr.ObsLightMicProjectErr("'%s' is not a file." % filePath)
        wantedPath = os.path.join(self.projectDirectory, self.__name + ".ks")

        if isinstance(wantedPath, unicode):
            wantedPath = str(wantedPath)

        if os.path.abspath(filePath) != wantedPath:
            tmpKsMngr = ObsLightKickstartManager(filePath)
            tmpKsMngr.saveKickstart(wantedPath)
        self.__kickstartPath = wantedPath
        self.__loadKsManager()

    def getKickstartFile(self):
        """
        Get the kickstart file of the project.
        """
        return self.__kickstartPath

    def saveKickstartFile(self, path=None):
        """
        Save the Kickstart of the project to `path`,
        or to the previous path if None.
        """
        self.kickstartManager.saveKickstart(path)

    def addKickstartRepository(self, baseurl, name, cost=None, **otherParams):
        """
        Add a package repository in the Kickstart file.
         baseurl: the URL of the repository
         name:    a name for this repository
         cost:    the cost of this repository, from 0 (highest priority) to 99, or None
        Keyword arguments can be (default value):
        - mirrorlist (""):
        - priority (None):
        - includepkgs ([]):
        - excludepkgs ([]):
        - save (False): keep the repository in the generated image
        - proxy (None):
        - proxy_username (None):
        - proxy_password (None):
        - debuginfo (False):
        - source (False):
        - gpgkey (None): the address of the GPG key of this repository
            on the generated filesystem (ex: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-meego)
        - disable (False): add the repository as disabled
        - ssl_verify ("yes"):
        """
        self.kickstartManager.addRepository(baseurl, name, cost, **otherParams)

    def removeKickstartRepository(self, name):
        """
        Remove the `name` package repository from the Kickstart file.
        """
        self.kickstartManager.removeRepository(name)

    def getKickstartRepositoryDictionaries(self):
        """
        Return a list of repository dictionaries.
        Each dictionary contains:
         baseurl: the URL of the repository
         name: a name for this repository
         cost: the cost of this repository (for yum), from 0 (highest priority) to 99, or None
         mirrorlist (""):
         priority (None): the priority of this repository (for zypper)
         includepkgs ([]):
         excludepkgs ([]):
         save (False): keep the repository in the generated image
         proxy (None):
         proxy_username (None):
         proxy_password (None):
         debuginfo (False):
         source (False):
         gpgkey (None): the address of the GPG key of this repository
                on the generated filesystem (ex: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-meego)
         disable (False): add the repository as disabled
         ssl_verify ("yes"):
        """
        repoList = []
        for repoName in self.kickstartManager.getRepositoryList():
            repoList.append(self.kickstartManager.getRepositoryDict(repoName))
        return repoList

    def addKickstartPackage(self, name, excluded=False):
        """
        Add the package `name` in the Kickstart file.
        "excluded" parameter allows to add package as "explicitly excluded"
        (defaults to False).
        """
        if excluded:
            self.kickstartManager.addExcludedPackage(name)
        else:
            self.kickstartManager.addPackage(name)

    def removeKickstartPackage(self, name):
        """
        Remove the package `name` from the Kickstart file.
        """
        # We don't know if package was explicitly excluded or not
        # so we try to remove it from both lists.
        self.kickstartManager.removePackage(name)
        self.kickstartManager.removeExcludedPackage(name)

    def getKickstartPackageDictionaries(self):
        """
        Get a list of package dictionaries. Each package dictionary
        has keys:
          "name": the name of the package
          "excluded": True of the package is explicitly excluded in the
                      Kickstart file (prefixed with '-')
        These package dictionaries can be used as input
        to `addKickstartPackage`.
        """
        pkgList = []
        for pkgName in self.kickstartManager.getPackageList():
            pkgList.append({"name": pkgName, "excluded": False})
        for pkgName in self.kickstartManager.getExcludedPackageList():
            pkgList.append({"name": pkgName, "excluded": True})
        return pkgList

    def addKickstartPackageGroup(self, name):
        """
        Add the package group `name` in the Kickstart file.
        """
        self.kickstartManager.addPackageGroup(name)

    def removeKickstartPackageGroup(self, name):
        """
        Remove the package group `name` from the Kickstart file.
        """
        self.kickstartManager.removePackageGroup(name)

    def getKickstartPackageGroupDictionaries(self):
        """
        Get a list of package group dictionaries. Each package dictionary
        has keys:
          "name": the name of the package group
        More keys will come...
        """
        pkgGrpList = []
        for grpName in self.kickstartManager.getPackageGroupList():
            pkgGrpList.append({"name": grpName})
        return pkgGrpList

    def addOrChangeKickstartCommand(self, fullText, command=None):
        """
        Add a new Kickstart command, or modify an existing one.
        To add a new command, just pass the whole commandline in `fullText`.
        To change an existing command, it is preferable to pass the command
        name (or an alias) in `command` so that the old commandline can be
        erased first.
        """
        self.kickstartManager.addOrChangeCommand(fullText, command)

    def removeKickstartCommand(self, command):
        """
        Remove `command` from the Kickstart file.
        `command` must be a command name or an alias,
        but not the whole text generated by a command.
        """
        self.kickstartManager.removeCommand(command)

    def getKickstartCommandDictionaries(self):
        """
        Get a list of Kickstart command dictionaries containing:
          "name": the command name
          "in_use": True if the command is used in the current Kickstart file, False otherwise
          "generated_text": the text that is printed in the Kickstart file by this command
          "aliases": a list of command aliases
        """
        return self.kickstartManager.getFilteredCommandDictList()

    def addOrChangeKickstartScript(self, name=None, script="", **kwargs):
        """
        Add a new Kickstart script, or modify an existing one.
        To add a new script, leave `name` at None.
        To change an existing script, you must pass the script name
        in `name`. `script` and other keyword args are those described
        in `getKickstartScriptDictionaries()`.
        """
        self.kickstartManager.addOrChangeScript(name, script, **kwargs)

    def removeKickstartScript(self, scriptName):
        """
        Remove script `scriptName` from the Kickstart file.
        """
        self.kickstartManager.removeScript(scriptName)

    def getKickstartScriptDictionaries(self):
        """
        Get a list of script dictionaries containing (default value):
          "name": the name of the script (generated by OBS Light)
          "type": the type of script, one of
               pykickstart.constants.[KS_SCRIPT_PRE, KS_SCRIPT_POST, KS_SCRIPT_TRACEBACK]
          "interp": the interpreter to use to run the script ('/bin/sh')
          "errorOnFail": whether to quit or continue the script if a command fails (False)
          "inChroot": whether to run inside chroot or not (False)
          "logfile": the path where to log the output of the script (None)
          "script": all the lines of the script
        """
        return self.kickstartManager.getScriptDictList()

    def addKickstartOverlayFile(self, source, destination):
        """
        Add a new overlay file in the target file system.
        `source` is the path where the file is currently located,
        `destination` is the path where the file will be copied
        in the target file system.
        """
        return self.kickstartManager.addOverlayFile(source, destination)

    def removeOverlayFile(self, source, destination):
        """
        Remove the overlay file which was to be copied
        from `source` to `destination` in the target file system.
        """
        return self.kickstartManager.removeOverlayFile(source, destination)

    def getKickstartOverlayFileDictionaries(self):
        """
        Get a list of overlay file dictionaries containing:
          "source": the path of the file to be copied
          "destination": the path where the file will be copied
                         in target file system
        """
        return self.kickstartManager.getOverlayFileDictList()
# --- end Kickstart management -----------------------------------------------

    def deleteProjectDirectory(self):
        """
        Recursively delete the project working directory.
        """
        return self.__subprocess("sudo rm -r %s" % self.projectDirectory)
#        shutil.rmtree(self.projectDirectory)

    def setArchitecture(self, arch):
        """
        Set the architecture of the project.
        """
        self.__architecture = arch

    def getArchitecture(self):
        """
        Get the architecture of the project.
        """
        return self.__architecture

    def setImageType(self, imageType):
        """
        Set the image type of the project.
        """
        self.__imageType = imageType

    def getImageType(self):
        """
        Get the image type of the project.
        """
        return self.__imageType

    def createImage(self):
        """
        Launch the build of an image.
        """
        self.failIsUserNotInUserGroup()
        timeString = time.strftime("%Y-%m-%d_%Hh%Mm") + str(time.time() % 1).split(".")[1]
        logFilePath = os.path.join(self.projectDirectory, "build_" + timeString, "buildLog")
#        cacheDirPath = os.path.join(self.projectDirectory, "cache")
        proxies = urllib.getproxies_environment()
        for scheme in proxies.keys():
            if scheme == 'http':
                cmd = "sudo sed -r -i 's,(; *)*proxy =.*,proxy = " + proxies[scheme] + ",' /etc/mic/mic.conf"
                self.__subprocess(cmd)

        cmd = "sudo mic --debug --verbose create " + self.getImageType()
        cmd += " " + self.getKickstartFile()
        cmd += " --logfile=" + logFilePath
#        cmd += " --cachedir=" + cacheDirPath
        cmd += " --outdir=" + self.projectDirectory
        cmd += " --arch=" + self.__architecture
#        cmd += " --release=build_" + timeString
        cmd += " --local-pkgs-path=" + self.localPackagesDirectory
        self.__subprocess(cmd)

    def getAvailableArchitectures(self):
        """
        Get the available architecture types as a list.
        """
        return ["i686","x86_64", "armv7l","armv7hl"]

    def getAvailableImageTypes(self):
        """
        Get the available image types as a list of strings.
        """
        return ["fs", "livecd", "liveusb", "loop" , "raw" ]

    def runQemu(self):
        #TO TEST
        #"sudo qemu-system-x86_64 -hda\
        # latest/images/meego-netbook-ia32-qemu_local/meego-netbook-ia32-qemu_local-latest-hda.raw\
        # -boot c -m 2047 -k fr -vnc :1 -smp 2 -serial pty -M pc -cpu core2duo\
        # -append "root=/dev/sda1 console=ttyS0,115200n8" -kernel\
        # ./kernel/vmlinuz-2.6.37.2-6 -initrd ./kernel/initrd-2.6.37.2-6.img -vga std -sdl"
        #sudo screen /dev/pts/5
        #vncviewer :1
        pass