def __init__(self, ctx):
     self._log = _log
     self._ctx = ctx
     self._unzipUtil = UnzipUtil(ctx)
     self._hashUtil = HashUtil(ctx)
     self._dcm = DirectoryCacheManager(ctx)
     self._dwn = self._get_downloader(ctx)(ctx)
 def __init__(self, ctx):
     self._log = _log
     self._ctx = ctx
     self._unzipUtil = UnzipUtil(ctx)
     self._hashUtil = HashUtil(ctx)
     self._dcm = DirectoryCacheManager(ctx)
     self._dwn = self._get_downloader(ctx)(ctx)
class CloudFoundryInstaller(object):
    def __init__(self, ctx):
        self._log = _log
        self._ctx = ctx
        self._unzipUtil = UnzipUtil(ctx)
        self._hashUtil = HashUtil(ctx)
        self._dcm = DirectoryCacheManager(ctx)
        self._dwn = self._get_downloader(ctx)(ctx)

    def _get_downloader(self, ctx):
        method = ctx.get('DOWNLOAD_METHOD', 'python')
        if method == 'python':
            self._log.debug('Using python downloader.')
            return Downloader
        elif method == 'curl':
            self._log.debug('Using cURL downloader.')
            return CurlDownloader
        elif method == 'custom':
            fullClsName = ctx['DOWNLOAD_CLASS']
            self._log.debug('Using custom downloader [%s].', fullClsName)
            dotLoc = fullClsName.rfind('.')
            if dotLoc >= 0:
                clsName = fullClsName[dotLoc + 1: len(fullClsName)]
                modName = fullClsName[0:dotLoc]
                m = __import__(modName, globals(), locals(), [clsName])
                try:
                    return getattr(m, clsName)
                except AttributeError:
                    self._log.exception(
                        'WARNING: DOWNLOAD_CLASS not found!')
            else:
                self._log.error(
                    'WARNING: DOWNLOAD_CLASS invalid, must include '
                    'package name!')
        return Downloader

    def _is_url(self, val):
        return urlparse(val).scheme != ''

    def install_binary_direct(self, url, hsh, installDir,
                              fileName=None, strip=False,
                              extract=True):
        self._log.debug("Installing direct [%s]", url)
        if not fileName:
            fileName = urlparse(url).path.split('/')[-1]
        if self._is_url(hsh):
            digest = self._dwn.download_direct(hsh)
        else:
            digest = hsh
        self._log.debug(
            "Installing [%s] with digest [%s] into [%s] with "
            "name [%s] stripping [%s]",
            url, digest, installDir, fileName, strip)
        fileToInstall = self._dcm.get(fileName, digest)
        if fileToInstall is None:
            self._log.debug('File [%s] not in cache.', fileName)
            fileToInstall = os.path.join(self._ctx['TMPDIR'], fileName)
            self._dwn.download(url, fileToInstall)
            digest = self._hashUtil.calculate_hash(fileToInstall)
            fileToInstall = self._dcm.put(fileName, fileToInstall, digest)
        if extract:
            return self._unzipUtil.extract(fileToInstall,
                                           installDir,
                                           strip)
        else:
            shutil.copy(fileToInstall, installDir)
            return installDir

    def install_binary(self, installKey):
        self._log.debug('Installing [%s]', installKey)
        url = self._ctx['%s_DOWNLOAD_URL' % installKey]
        hashUrl = self._ctx.get(
            '%s_HASH_DOWNLOAD_URL' % installKey,
            "%s.%s" % (url, self._ctx['CACHE_HASH_ALGORITHM']))
        installDir = os.path.join(self._ctx['BUILD_DIR'],
                                  self._ctx.get(
                                      '%s_PACKAGE_INSTALL_DIR' % installKey,
                                      installKey.lower()))
        strip = self._ctx.get('%s_STRIP' % installKey, False)
        return self.install_binary_direct(url, hashUrl, installDir,
                                          strip=strip)

    def _install_from(self, fromPath, fromLoc, toLocation=None, ignore=None):
        """Copy file or directory from a location to the droplet

        Copies a file or directory from a location to the application
        droplet. Directories are copied recursively, but specific files
        in those directories can be ignored by specifing the ignore parameter.

            fromPath   -> file to copy, relative build pack
            fromLoc    -> root of the from path.  Full path to file or
                          directory to be copied is fromLoc + fromPath
            toLocation -> optional location where to copy the file
                          relative to app droplet.  If not specified
                          uses fromPath.
            ignore     -> an optional callable that is passed to
                          the ignore argument of shutil.copytree.
        """
        self._log.debug("Install file [%s] from [%s]", fromPath, fromLoc)
        fullPathFrom = os.path.join(fromLoc, fromPath)
        if os.path.exists(fullPathFrom):
            fullPathTo = os.path.join(
                self._ctx['BUILD_DIR'],
                ((toLocation is None) and fromPath or toLocation))
            safe_makedirs(os.path.dirname(fullPathTo))
            self._log.debug("Copying [%s] to [%s]", fullPathFrom, fullPathTo)
            if os.path.isfile(fullPathFrom):
                shutil.copy(fullPathFrom, fullPathTo)
            else:
                utils.copytree(fullPathFrom, fullPathTo, ignore=ignore)

    def install_from_build_pack(self, fromPath, toLocation=None, ignore=None):
        """Copy file or directory from the build pack to the droplet

        Copies a file or directory from the build pack to the application
        droplet. Directories are copied recursively, but specific files
        in those directories can be ignored by specifing the ignore parameter.

            fromPath   -> file to copy, relative build pack
            toLocation -> optional location where to copy the file
                          relative to app droplet.  If not specified
                          uses fromPath.
            ignore     -> an optional callable that is passed to
                          the ignore argument of shutil.copytree.
        """
        self._install_from(
            fromPath,
            self._ctx['BP_DIR'],
            toLocation,
            ignore)

    def install_from_application(self, fromPath, toLocation, ignore=None):
        """Copy file or directory from one place to another in the application

        Copies a file or directory from one place to another place within the
        application droplet.

            fromPath   -> file or directory to copy, relative
                          to application droplet.
            toLocation -> location where to copy the file,
                          relative to app droplet.
            ignore     -> optional callable that is passed to the
                          ignore argument of shutil.copytree
        """
        self._install_from(
            fromPath,
            self._ctx['BUILD_DIR'],
            toLocation,
            ignore)
class CloudFoundryInstaller(object):
    def __init__(self, ctx):
        self._log = _log
        self._ctx = ctx
        self._unzipUtil = UnzipUtil(ctx)
        self._hashUtil = HashUtil(ctx)
        self._dcm = DirectoryCacheManager(ctx)
        self._dwn = self._get_downloader(ctx)(ctx)

    def _get_downloader(self, ctx):
        method = ctx.get('DOWNLOAD_METHOD', 'python')
        if method == 'python':
            self._log.debug('Using python downloader.')
            return Downloader
        elif method == 'curl':
            self._log.debug('Using cURL downloader.')
            return CurlDownloader
        elif method == 'custom':
            fullClsName = ctx['DOWNLOAD_CLASS']
            self._log.debug('Using custom downloader [%s].', fullClsName)
            dotLoc = fullClsName.rfind('.')
            if dotLoc >= 0:
                clsName = fullClsName[dotLoc + 1: len(fullClsName)]
                modName = fullClsName[0:dotLoc]
                m = __import__(modName, globals(), locals(), [clsName])
                try:
                    return getattr(m, clsName)
                except AttributeError:
                    self._log.exception(
                        'WARNING: DOWNLOAD_CLASS not found!')
            else:
                self._log.error(
                    'WARNING: DOWNLOAD_CLASS invalid, must include '
                    'package name!')
        return Downloader

    def _is_url(self, val):
        return urlparse(val).scheme != ''

    def install_binary_direct(self, url, hsh, installDir,
                              fileName=None, strip=False,
                              extract=True):
        self._log.debug("Installing direct [%s]", url)
        if not fileName:
            fileName = url.split('/')[-1]
        if self._is_url(hsh):
            digest = self._dwn.download_direct(hsh)
        else:
            digest = hsh
        self._log.debug(
            "Installing [%s] with digest [%s] into [%s] with "
            "name [%s] stripping [%s]",
            url, digest, installDir, fileName, strip)
        fileToInstall = self._dcm.get(fileName, digest)
        if fileToInstall is None:
            self._log.debug('File [%s] not in cache.', fileName)
            fileToInstall = os.path.join(self._ctx['TMPDIR'], fileName)
            self._dwn.download(url, fileToInstall)
            digest = self._hashUtil.calculate_hash(fileToInstall)
            fileToInstall = self._dcm.put(fileName, fileToInstall, digest)
        if extract:
            return self._unzipUtil.extract(fileToInstall,
                                           installDir,
                                           strip)
        else:
            shutil.copy(fileToInstall, installDir)
            return installDir

    def install_binary(self, installKey):
        self._log.debug('Installing [%s]', installKey)
        url = self._ctx['%s_DOWNLOAD_URL' % installKey]
        hashUrl = self._ctx.get(
            '%s_HASH_DOWNLOAD_URL' % installKey,
            "%s.%s" % (url, self._ctx['CACHE_HASH_ALGORITHM']))
        installDir = os.path.join(self._ctx['BUILD_DIR'],
                                  self._ctx.get(
                                      '%s_PACKAGE_INSTALL_DIR' % installKey,
                                      installKey.lower()))
        strip = self._ctx.get('%s_STRIP' % installKey, False)
        return self.install_binary_direct(url, hashUrl, installDir,
                                          strip=strip)

    def _install_from(self, fromPath, fromLoc, toLocation=None, ignore=None):
        """Copy file or directory from a location to the droplet

        Copies a file or directory from a location to the application
        droplet. Directories are copied recursively, but specific files
        in those directories can be ignored by specifing the ignore parameter.

            fromPath   -> file to copy, relative build pack
            fromLoc    -> root of the from path.  Full path to file or
                          directory to be copied is fromLoc + fromPath
            toLocation -> optional location where to copy the file
                          relative to app droplet.  If not specified
                          uses fromPath.
            ignore     -> an optional callable that is passed to
                          the ignore argument of shutil.copytree.
        """
        self._log.debug("Install file [%s] from [%s]", fromPath, fromLoc)
        fullPathFrom = os.path.join(fromLoc, fromPath)
        if os.path.exists(fullPathFrom):
            fullPathTo = os.path.join(
                self._ctx['BUILD_DIR'],
                ((toLocation is None) and fromPath or toLocation))
            safe_makedirs(os.path.dirname(fullPathTo))
            self._log.debug("Copying [%s] to [%s]", fullPathFrom, fullPathTo)
            if os.path.isfile(fullPathFrom):
                shutil.copy(fullPathFrom, fullPathTo)
            else:
                utils.copytree(fullPathFrom, fullPathTo, ignore=ignore)

    def install_from_build_pack(self, fromPath, toLocation=None, ignore=None):
        """Copy file or directory from the build pack to the droplet

        Copies a file or directory from the build pack to the application
        droplet. Directories are copied recursively, but specific files
        in those directories can be ignored by specifing the ignore parameter.

            fromPath   -> file to copy, relative build pack
            toLocation -> optional location where to copy the file
                          relative to app droplet.  If not specified
                          uses fromPath.
            ignore     -> an optional callable that is passed to
                          the ignore argument of shutil.copytree.
        """
        self._install_from(
            fromPath,
            self._ctx['BP_DIR'],
            toLocation,
            ignore)

    def install_from_application(self, fromPath, toLocation, ignore=None):
        """Copy file or directory from one place to another in the application

        Copies a file or directory from one place to another place within the
        application droplet.

            fromPath   -> file or directory to copy, relative
                          to application droplet.
            toLocation -> location where to copy the file,
                          relative to app droplet.
            ignore     -> optional callable that is passed to the
                          ignore argument of shutil.copytree
        """
        self._install_from(
            fromPath,
            self._ctx['BUILD_DIR'],
            toLocation,
            ignore)