예제 #1
0
    def startdownload(self):
        """
        Download using http. The protocol is chosen based on package uri.
        Target folder is packageloc relative to repo_root.
        """
        try:
            utils.checkDiskFull()
            reqjson = json.loads(request.body)
            
            package = reqjson['package']
            packageloc = str(reqjson['packageloc'])

            LOG.info('Request received for StartDownload %s' % packageloc)
            appGlobal = config['pylons.app_globals']
            
            LOG.info('Starting a new StartDownload Thread %s' % package)
            if type(package) == list:
                downloadThread = PackageDownload(appGlobal.threadMgr, package)
            else:
                cat = PackageUtil.getPackageKey(package)
                downloadThread = DownloadThread(appGlobal.threadMgr, package, packageloc, category = [cat])

            self.injectJobCtx(downloadThread)
            downloadThread.start()
            downloadThread.threadMgrEvent.wait()

            return statusResult(request, response, downloadThread, controller = self)
        except AgentException as excep:
            return errorResult(request, response, error = excep.getCode(), errorMsg = excep.getMsg(), controller = self)
        except Exception as excp:
            errorMsg = 'Exception downloading %s - traceback %s' % (str(excp), traceback.format_exc(2))
            return errorResult(request, response, error = Errors.UNKNOWN_ERROR, errorMsg = errorMsg, controller = self)
예제 #2
0
    def _downloadPackages(self, packages, isFailedFatal = True):
        """
        download all the packages
        update progress
        check for timeout

        @params packages = list of package uri's
        @throws AgentException
        """
        try:
            appGlobal = pylons.config['pylons.app_globals']

            # globals all the remaining packages, download the packages
            pkgObjs = []
            for pkg in packages:
                packageKey = PackageUtil.getPackageKey(pkg)
                matchDlThreads = appGlobal.threadMgr.getThreadByCat(packageKey)
                if matchDlThreads:
                    # found an inprogress download thread
                    dlThread = matchDlThreads[0]
                else:
                    dlThread = DownloadThread(self._threadMgr, pkg, category=[packageKey], packageloc=None, parentId = self.getUuid())
                    contextutils.copyJobContexts(self, dlThread)
                    dlThread.start()

                if (dlThread.getStatus().get('progress') != 100):
                    pkgObjs.append(dlThread)

                self._checkStop()

            # check that we have packages to download
            if (len(pkgObjs) == 0):
                return [] # nothing to download, so no failed packages

            # now wait for all the packages to finish
            liveThreadCount = len(pkgObjs)
            timeoutNotSet = True
            create_sleep_time = float(pylons.config['exec_thread_sleep_time']) * liveThreadCount
            failed_packages = []
            
            while (liveThreadCount > 0):
                self._checkStop()
                LOG.info('%s packages still downloading' % liveThreadCount)
                time.sleep(create_sleep_time)

                # go through all the packages and
                # calculated average progress
                # check that all packages are alive
                totalProgress = 0
                liveThreadCount = 0

                timeouts = (0.0, 0.0)
                for dlThread in pkgObjs:
                    
                    # we are not done yet
                    if dlThread.isAlive():
                        liveThreadCount += 1
                        
                    # if one package failed, then we have to fail the entire manifest
                    threadStatus = dlThread.getStatus()
                    if (not dlThread.isAlive() and threadStatus.get('progress') != 100):
                        if isFailedFatal:
                            raise AgentException(Errors.DC_FAILED_DOWNLOAD,
                                             'failed downloading package (%s) - %s'
                                             % (dlThread.getUriDict().get('uri'), threadStatus.get('errorMsg')))
                        failed_packages.append(dlThread.getUriDict().get('uri'))
                        
                    progressTimeout = dlThread.getProgressTimeouts()
                    if (progressTimeout and timeouts):
                        timeouts = (timeouts[0] + progressTimeout[0], timeouts[1] + progressTimeout[1])
                    else:
                        timeouts = None
                    pkgProgress = threadStatus.get('progress')
                    totalProgress += pkgProgress
                    
                if (timeouts and timeoutNotSet):
                    # Setting the timeout once as it is absolute time.  Doing this after the timeout for each
                    # package is available
                    self.extendTimeout(timeouts[0])
                    timeoutNotSet = False
                    LOG.debug('Using overall timeout=%s and progress timeout=%s' % (timeouts[0], timeouts[1]))

                # calculate the new progress
                # I'm allocating 80 of the progress to be the download
                newProgress = calcProgress(1, 79, float(totalProgress) / (100 * len(pkgObjs)))

                # now update the pgoress
                self._updateProgress(newProgress)


            return failed_packages

        finally:
            # now update the pgoress
            self._updateProgress(79)