Пример #1
0
    def getMetaData(self):
        if self.packageControlFile:
            # Already done
            return

        logger.info(u"Getting meta data from package '%s'" % self.packageFile)

        try:
            if not os.path.exists(self.tmpUnpackDir):
                os.mkdir(self.tmpUnpackDir)
                os.chmod(self.tmpUnpackDir, 0o700)

            metaDataTmpDir = os.path.join(self.tmpUnpackDir, u'OPSI')
            archive = Archive(self.packageFile)

            logger.debug(u"Extracting meta data from package '%s' to: '%s'" %
                         (self.packageFile, metaDataTmpDir))
            archive.extract(targetPath=metaDataTmpDir, patterns=[u"OPSI*"])

            metadataArchives = []
            for f in os.listdir(metaDataTmpDir):
                if not f.endswith(
                    (u'.cpio.gz', u'.tar.gz', u'.cpio', u'.tar')):
                    logger.warning(u"Unknown content in archive: %s" % f)
                    continue
                logger.debug(u"Metadata archive found: %s" % f)
                metadataArchives.append(f)
            if not metadataArchives:
                raise ValueError(u"No metadata archive found")
            if len(metadataArchives) > 2:
                raise ValueError(u"More than two metadata archives found")

            # Sorting to unpack custom version metadata at last
            metadataArchives.sort()

            for metadataArchive in metadataArchives:
                archive = Archive(os.path.join(metaDataTmpDir,
                                               metadataArchive))
                archive.extract(targetPath=metaDataTmpDir)

            packageControlFile = os.path.join(metaDataTmpDir, u'control')
            if not os.path.exists(packageControlFile):
                raise IOError(
                    u"No control file found in package metadata archives")

            self.packageControlFile = PackageControlFile(packageControlFile)
            self.packageControlFile.parse()

        except Exception as e:
            logger.logException(e)
            self.cleanup()
            raise RuntimeError(
                u"Failed to get metadata from package '%s': %s" %
                (self.packageFile, e))
        logger.debug(u"Got meta data from package '%s'" % self.packageFile)
        return self.packageControlFile
Пример #2
0
    def pack(self, progressSubject=None):
        # Create temporary directory
        if os.path.exists(self.tmpPackDir):
            shutil.rmtree(self.tmpPackDir)
        os.mkdir(self.tmpPackDir)

        archives = []
        diskusage = 0
        dirs = [u'CLIENT_DATA', u'SERVER_DATA', u'OPSI']

        try:
            if self.customName:
                found = False
                for i, currentDir in enumerate(dirs):
                    customDir = u"%s.%s" % (currentDir, self.customName)
                    if os.path.exists(
                            os.path.join(self.packageSourceDir, customDir)):
                        found = True
                        if self.customOnly:
                            dirs[i] = customDir
                        else:
                            dirs.append(customDir)
                if not found:
                    raise RuntimeError(u"No custom dirs found for '%s'" %
                                       self.customName)

            # Try to define diskusage from Sourcedirectory to prevent a override from cpio sizelimit.
            for d in dirs:
                if not os.path.exists(os.path.join(self.packageSourceDir,
                                                   d)) and d != u'OPSI':
                    logger.info(u"Directory '%s' does not exist" %
                                os.path.join(self.packageSourceDir, d))
                    continue
                fileList = findFiles(os.path.join(self.packageSourceDir, d),
                                     excludeDir=EXCLUDE_DIRS_ON_PACK_REGEX,
                                     excludeFile=EXCLUDE_FILES_ON_PACK_REGEX,
                                     followLinks=self.dereference)
                if fileList:
                    for f in fileList:
                        diskusage = diskusage + os.path.getsize(
                            os.path.join(self.packageSourceDir, d, f))

            if diskusage >= 2147483648:
                logger.info(
                    u"Switching to tar format, because sourcefiles overrides cpio sizelimit."
                )
                self.format = u'tar'

            for d in dirs:
                if not os.path.exists(os.path.join(self.packageSourceDir,
                                                   d)) and d != u'OPSI':
                    logger.info(u"Directory '%s' does not exist" %
                                os.path.join(self.packageSourceDir, d))
                    continue

                fileList = findFiles(os.path.join(self.packageSourceDir, d),
                                     excludeDir=EXCLUDE_DIRS_ON_PACK_REGEX,
                                     excludeFile=EXCLUDE_FILES_ON_PACK_REGEX,
                                     followLinks=self.dereference)

                if d.startswith(u'SERVER_DATA'):
                    # Never change permissions of existing directories in /
                    tmp = []
                    for f in fileList:
                        if f.find(os.sep) == -1:
                            logger.info(u"Skipping dir '%s'" % f)
                            continue
                        tmp.append(f)

                    fileList = tmp

                if not fileList:
                    logger.notice(u"Skipping empty dir '%s'" %
                                  os.path.join(self.packageSourceDir, d))
                    continue

                filename = os.path.join(self.tmpPackDir,
                                        u'%s.%s' % (d, self.format))
                if self.compression == 'gzip':
                    filename += u'.gz'
                elif self.compression == 'bzip2':
                    filename += u'.bz2'
                archive = Archive(filename,
                                  format=self.format,
                                  compression=self.compression,
                                  progressSubject=progressSubject)
                if progressSubject:
                    progressSubject.reset()
                    progressSubject.setMessage(
                        u'Creating archive %s' %
                        os.path.basename(archive.getFilename()))
                archive.create(fileList=fileList,
                               baseDir=os.path.join(self.packageSourceDir, d),
                               dereference=self.dereference)
                archives.append(filename)

            archive = Archive(self.packageFile,
                              format=self.format,
                              compression=None,
                              progressSubject=progressSubject)
            if progressSubject:
                progressSubject.reset()
                progressSubject.setMessage(
                    u'Creating archive %s' %
                    os.path.basename(archive.getFilename()))
            archive.create(fileList=archives, baseDir=self.tmpPackDir)
        except Exception as e:
            self.cleanup()
            raise RuntimeError(u"Failed to create package '%s': %s" %
                               (self.packageFile, e))
Пример #3
0
    def extractData(self):
        logger.info(u"Extracting data from package '%s'" % self.packageFile)

        try:
            if not self.packageControlFile:
                raise ValueError(u"Metadata not present")

            if not self.clientDataDir:
                raise ValueError(u"Client data dir not set")

            self.clientDataFiles = []

            archive = Archive(self.packageFile)

            logger.info(u"Extracting data from package '%s' to: '%s'" %
                        (self.packageFile, self.tmpUnpackDir))
            archive.extract(targetPath=self.tmpUnpackDir,
                            patterns=[u"CLIENT_DATA*", u"SERVER_DATA*"])

            clientDataArchives = []
            serverDataArchives = []
            for f in os.listdir(self.tmpUnpackDir):
                if f.startswith('OPSI'):
                    continue

                if not f.endswith(
                    (u'.cpio.gz', u'.tar.gz', u'.cpio', u'.tar')):
                    logger.warning(u"Unknown content in archive: %s" % f)
                    continue

                if f.startswith('CLIENT_DATA'):
                    logger.debug(u"Client-data archive found: %s" % f)
                    clientDataArchives.append(f)
                elif f.startswith('SERVER_DATA'):
                    logger.debug(u"Server-data archive found: %s" % f)
                    serverDataArchives.append(f)

            if not clientDataArchives:
                logger.warning(u"No client-data archive found")
            if len(clientDataArchives) > 2:
                raise ValueError(u"More than two client-data archives found")
            if len(serverDataArchives) > 2:
                raise ValueError(u"More than two server-data archives found")

            # Sorting to unpack custom version data at last
            def psort(name):
                return re.sub(r'(\.tar|\.tar\.gz|\.cpio|\.cpio\.gz)$', '',
                              name)

            clientDataArchives = sorted(clientDataArchives, key=psort)
            serverDataArchives = sorted(serverDataArchives, key=psort)

            for serverDataArchive in serverDataArchives:
                archiveFile = os.path.join(self.tmpUnpackDir,
                                           serverDataArchive)
                logger.info(u"Extracting server-data archive '%s' to '/'" %
                            archiveFile)
                archive = Archive(archiveFile)
                archive.extract(targetPath=u'/')

            productClientDataDir = self.getProductClientDataDir()
            if not os.path.exists(productClientDataDir):
                os.mkdir(productClientDataDir)
                os.chmod(productClientDataDir, 0o2770)

            for clientDataArchive in clientDataArchives:
                archiveFile = os.path.join(self.tmpUnpackDir,
                                           clientDataArchive)
                logger.info(u"Extracting client-data archive '%s' to '%s'" %
                            (archiveFile, productClientDataDir))
                archive = Archive(archiveFile)
                archive.extract(targetPath=productClientDataDir)

            logger.debug(u"Finished extracting data from package")
        except Exception as e:
            self.cleanup()
            raise RuntimeError(
                u"Failed to extract data from package '%s': %s" %
                (self.packageFile, e))
Пример #4
0
    def unpackSource(self,
                     destinationDir=u'.',
                     newProductId=None,
                     progressSubject=None):
        logger.info(u"Extracting package source from '%s'" % self.packageFile)
        if progressSubject:
            progressSubject.setMessage(
                _(u"Extracting package source from '%s'") % self.packageFile)

        try:
            destinationDir = forceFilename(destinationDir)
            if newProductId:
                newProductId = forceUnicode(newProductId)

            archive = Archive(filename=self.packageFile,
                              progressSubject=progressSubject)

            logger.debug(u"Extracting source from package '%s' to: '%s'" %
                         (self.packageFile, destinationDir))

            if progressSubject:
                progressSubject.setMessage(_(u'Extracting archives'))
            archive.extract(targetPath=self.tmpUnpackDir)

            for f in os.listdir(self.tmpUnpackDir):
                logger.info(u"Processing file '%s'" % f)
                archiveName = u''
                if f.endswith('.cpio.gz'):
                    archiveName = f[:-8]
                elif f.endswith('.cpio'):
                    archiveName = f[:-5]
                elif f.endswith('.tar.gz'):
                    archiveName = f[:-7]
                elif f.endswith('.tar'):
                    archiveName = f[:-4]
                elif f.startswith('OPSI'):
                    continue
                else:
                    logger.warning(u"Unknown content in archive: %s" % f)
                    continue
                archive = Archive(filename=os.path.join(self.tmpUnpackDir, f),
                                  progressSubject=progressSubject)
                if progressSubject:
                    progressSubject.setMessage(
                        _(u'Extracting archive %s') % archiveName)
                archive.extract(
                    targetPath=os.path.join(destinationDir, archiveName))

            if newProductId:
                self.getMetaData()
                product = self.packageControlFile.getProduct()
                for scriptName in (u'setupScript', u'uninstallScript',
                                   u'updateScript', u'alwaysScript',
                                   u'onceScript', u'customScript'):
                    script = getattr(product, scriptName)
                    if not script:
                        continue
                    newScript = script.replace(product.id, newProductId)
                    if not os.path.exists(
                            os.path.join(destinationDir, u'CLIENT_DATA',
                                         script)):
                        logger.warning(
                            u"Script file '%s' not found" % os.path.join(
                                destinationDir, u'CLIENT_DATA', script))
                        continue
                    os.rename(
                        os.path.join(destinationDir, u'CLIENT_DATA', script),
                        os.path.join(destinationDir, u'CLIENT_DATA',
                                     newScript))
                    setattr(product, scriptName, newScript)
                product.setId(newProductId)
                self.packageControlFile.setProduct(product)
                self.packageControlFile.setFilename(
                    os.path.join(destinationDir, u'OPSI', u'control'))
                self.packageControlFile.generate()
            logger.debug(u"Finished extracting package source")
        except Exception as e:
            logger.logException(e, LOG_INFO)
            self.cleanup()
            raise RuntimeError(
                u"Failed to extract package source from '%s': %s" %
                (self.packageFile, e))
Пример #5
0
def testRaisingExceptionIfFiletypeCanNotBeDetermined():
    with pytest.raises(Exception):
        Archive(__file__)
Пример #6
0
def testCreatingArchive(fileFormat):
    Archive('no_file', format=fileFormat)
Пример #7
0
def testArchiveFactoryRaisesExceptionOnUnknownFormat():
    with pytest.raises(Exception):
        Archive('no_filename', format='unknown')