def install_extension(self, install_url, package_name): """Install an extension from a remote source. Installs an extension from a remote URL containing the extension egg. Installation may fail if a malformed install_url or package_name is passed, which will cause an InstallExtensionError exception to be raised. It is also assumed that the extension is not already installed. """ try: easy_install.main(["-U", install_url]) # Update the entry points. dist = pkg_resources.get_distribution(package_name) dist.activate() pkg_resources.working_set.add(dist) except pkg_resources.DistributionNotFound: raise InstallExtensionError(_("Invalid package name.")) except SystemError: raise InstallExtensionError( _('Installation failed (probably malformed URL).')) # Refresh the extension manager. self.load(True)
def _migrate_extension_models(self, ext_class): """Perform database migrations for an extension's models. This will call out to Django Evolution to handle the migrations. Args: ext_class (djblets.extensions.extension.Extension): The class for the extension to migrate. """ try: from django_evolution.management.commands.evolve import \ Command as Evolution except ImportError: raise InstallExtensionError( "Unable to migrate the extension's database tables. Django " "Evolution is not installed.") try: stream = StringIO() evolution = Evolution() evolution.style = no_style() evolution.execute(verbosity=0, interactive=False, execute=True, hint=False, compile_sql=False, purge=False, database=False, stdout=stream, stderr=stream) output = stream.getvalue() if output: logging.info('Evolved extension models for %s: %s', ext_class.id, stream.read()) stream.close() except CommandError as e: # Something went wrong while running django-evolution, so # grab the output. We can't raise right away because we # still need to put stdout back the way it was output = stream.getvalue() stream.close() logging.error('Error evolving extension models: %s: %s', e, output, exc_info=1) load_error = self._store_load_error(ext_class.id, output) raise InstallExtensionError(six.text_type(e), load_error)
def _install_extension(self, ext_class): """Installs extension data. Performs any installation necessary for an extension. This will install the contents of htdocs into the EXTENSIONS_STATIC_ROOT directory. """ ext_path = ext_class.info.htdocs_path ext_path_exists = os.path.exists(ext_path) if ext_path_exists: # First, get rid of the old htdocs contents, so we can start # fresh. shutil.rmtree(ext_path, ignore_errors=True) if pkg_resources.resource_exists(ext_class.__module__, "htdocs"): # Now install any new htdocs contents. extracted_path = \ pkg_resources.resource_filename(ext_class.__module__, "htdocs") shutil.copytree(extracted_path, ext_path, symlinks=True) # Mark the extension as installed ext_class.registration.installed = True ext_class.registration.save() # Now let's build any tables that this extension might need self._add_to_installed_apps(ext_class) # Call syncdb to create the new tables loading.cache.loaded = False call_command('syncdb', verbosity=0, interactive=False) # Run evolve to do any table modification try: evolution = Evolution() evolution.evolve(verbosity=0, interactive=False, execute=True, hint=False, compile_sql=False, purge=False, database=False) except CommandError, e: # Something went wrong while running django-evolution, so # grab the output. We can't raise right away because we # still need to put stdout back the way it was logging.error(e.message) raise InstallExtensionError(e.message)
def _migrate_extension_models(self, ext_class): """Perform database migrations for an extension's models. This will call out to Django Evolution to handle the migrations. Args: ext_class (djblets.extensions.extension.Extension): The class for the extension to migrate. """ if django_evolution is None: # Django Evolution isn't installed. Extensions with evolutions # are not supported. return try: stream = StringIO() call_command('evolve', verbosity=0, interactive=False, execute=True, stdout=stream, stderr=stream) output = stream.getvalue() if output: logging.info('Evolved extension models for %s: %s', ext_class.id, stream.read()) stream.close() except CommandError as e: # Something went wrong while running django-evolution, so # grab the output. We can't raise right away because we # still need to put stdout back the way it was output = stream.getvalue() stream.close() logging.error('Error evolving extension models: %s: %s', e, output, exc_info=1) load_error = self._store_load_error(ext_class.id, output) raise InstallExtensionError(six.text_type(e), load_error)
def _install_extension(self, ext_class): """Installs extension data. Performs any installation necessary for an extension. This will install the contents of htdocs into the EXTENSIONS_STATIC_ROOT directory. """ ext_htdocs_path = ext_class.info.installed_htdocs_path ext_htdocs_path_exists = os.path.exists(ext_htdocs_path) if ext_htdocs_path_exists: # First, get rid of the old htdocs contents, so we can start # fresh. shutil.rmtree(ext_htdocs_path, ignore_errors=True) if pkg_resources.resource_exists(ext_class.__module__, 'htdocs'): # This is an older extension that doesn't use the static file # support. Log a deprecation notice and then install the files. logging.warning('The %s extension uses the deprecated "htdocs" ' 'directory for static files. It should be updated ' 'to use a "static" directory instead.' % ext_class.info.name) extracted_path = \ pkg_resources.resource_filename(ext_class.__module__, 'htdocs') shutil.copytree(extracted_path, ext_htdocs_path, symlinks=True) # We only want to install static media on a non-DEBUG install. # Otherwise, we run the risk of creating a new 'static' directory and # causing Django to look up all static files (not just from # extensions) from there instead of from their source locations. if not settings.DEBUG: ext_static_path = ext_class.info.installed_static_path ext_static_path_exists = os.path.exists(ext_static_path) if ext_static_path_exists: # Also get rid of the old static contents. shutil.rmtree(ext_static_path, ignore_errors=True) if pkg_resources.resource_exists(ext_class.__module__, 'static'): extracted_path = \ pkg_resources.resource_filename(ext_class.__module__, 'static') shutil.copytree(extracted_path, ext_static_path, symlinks=True) # Mark the extension as installed ext_class.registration.installed = True ext_class.registration.save() # Now let's build any tables that this extension might need self._add_to_installed_apps(ext_class) # Call syncdb to create the new tables loading.cache.loaded = False call_command('syncdb', verbosity=0, interactive=False) # Run evolve to do any table modification try: evolution = Evolution() evolution.evolve(verbosity=0, interactive=False, execute=True, hint=False, compile_sql=False, purge=False, database=False) except CommandError as e: # Something went wrong while running django-evolution, so # grab the output. We can't raise right away because we # still need to put stdout back the way it was logging.error('Error evolving extension models: %s', e, exc_info=1) load_error = self._store_load_error(extension_id, e) raise InstallExtensionError(six.text_type(e), load_error) # Remove this again, since we only needed it for syncdb and # evolve. _init_extension will add it again later in # the install. self._remove_from_installed_apps(ext_class) # Mark the extension as installed ext_class.registration.installed = True ext_class.registration.save()