From 548e0ebd60cae4ea7aaf94ca8769c6963c6a3714 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Wed, 31 Aug 2016 19:09:02 -0400 Subject: [PATCH] Add --setup-no-install command Acts the same as --setup, but does not install any packages. Will raise an error if any required package is not already installed. --- INSTALL | 1 + plinth/__main__.py | 12 ++++++++---- plinth/errors.py | 5 +++++ plinth/setup.py | 17 ++++++++++++++--- requirements.txt | 1 + setup.py | 1 + 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/INSTALL b/INSTALL index 68bf9726e..b0d79f022 100644 --- a/INSTALL +++ b/INSTALL @@ -20,6 +20,7 @@ ppp \ pppoe \ python3 \ + python3-apt \ python3-augeas \ python3-bootstrapform \ python3-cherrypy3 \ diff --git a/plinth/__main__.py b/plinth/__main__.py index 394c1fd82..b5ecc5b99 100644 --- a/plinth/__main__.py +++ b/plinth/__main__.py @@ -21,7 +21,6 @@ import django.conf from django.contrib.messages import constants as message_constants import django.core.management import django.core.wsgi -from django.utils import translation import importlib import logging import os @@ -55,6 +54,9 @@ def parse_arguments(): parser.add_argument( '--setup', default=False, nargs='*', help='run setup tasks on all essential modules and exit') + parser.add_argument( + '--setup-no-install', default=False, nargs='*', + help='run setup tasks without installing packages and exit') parser.add_argument( '--diagnose', action='store_true', default=False, help='run diagnostic tests and exit') @@ -249,14 +251,14 @@ def configure_django(): os.chmod(cfg.store_file, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP) -def run_setup_and_exit(module_list): +def run_setup_and_exit(module_list, allow_install=True): """Run setup on all essential modules and exit.""" error_code = 0 try: if not module_list: - setup.setup_modules(essential=True) + setup.setup_modules(essential=True, allow_install=allow_install) else: - setup.setup_modules(module_list) + setup.setup_modules(module_list, allow_install=allow_install) except Exception as exception: logger.error('Error running setup - %s', exception) error_code = 1 @@ -302,6 +304,8 @@ def main(): module_loader.load_modules() if arguments.setup is not False: run_setup_and_exit(arguments.setup) + if arguments.setup_no_install is not False: + run_setup_and_exit(arguments.setup, allow_install=False) if arguments.diagnose: run_diagnostics_and_exit() diff --git a/plinth/errors.py b/plinth/errors.py index 097095bcb..0c9273228 100644 --- a/plinth/errors.py +++ b/plinth/errors.py @@ -33,3 +33,8 @@ class ActionError(PlinthError): class DomainRegistrationError(PlinthError): """Domain registration failed""" pass + + +class PackageNotInstalledError(PlinthError): + """Could not complete module setup due to missing package.""" + pass diff --git a/plinth/setup.py b/plinth/setup.py index 019ab0f04..9b99271ca 100644 --- a/plinth/setup.py +++ b/plinth/setup.py @@ -19,10 +19,12 @@ Plinth module with utilites for performing application setup operations. """ +import apt import logging import threading from . import package +from .errors import PackageNotInstalledError import plinth logger = logging.getLogger(__name__) @@ -58,7 +60,7 @@ class Helper(object): self.is_finished = None return exception - def run(self): + def run(self, allow_install=True): """Execute the setup process.""" # Setup for the module is already running if self.current_operation: @@ -68,6 +70,7 @@ class Helper(object): if current_version >= self.module.version: return + self.allow_install = allow_install self.exception = None self.current_operation = None self.is_finished = False @@ -89,6 +92,14 @@ class Helper(object): def install(self, package_names): """Install a set of packages marking progress.""" + if self.allow_install is False: + # Raise error if packages are not already installed. + cache = apt.Cache() + for package_name in package_names: + if not cache[package_name].is_installed: + raise PackageNotInstalledError(package_name) + return + logger.info('Running install for module - %s, packages - %s', self.module_name, package_names) @@ -150,7 +161,7 @@ def init(module_name, module): module.setup_helper = Helper(module_name, module) -def setup_modules(module_list=None, essential=False): +def setup_modules(module_list=None, essential=False, allow_install=True): """Run setup on selected or essential modules.""" logger.info('Running setup for modules, essential - %s, ' 'selected modules - %s', essential, module_list) @@ -161,4 +172,4 @@ def setup_modules(module_list=None, essential=False): if module_list and module_name not in module_list: continue - module.setup_helper.run() + module.setup_helper.run(allow_install=allow_install) diff --git a/requirements.txt b/requirements.txt index 529e340d4..7f1697565 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,6 @@ coverage >= 3.7 django >= 1.10.0 django-stronghold psutil +python-apt python-augeas ruamel.yaml diff --git a/setup.py b/setup.py index bf9d7047f..f2e4172e6 100755 --- a/setup.py +++ b/setup.py @@ -184,6 +184,7 @@ setuptools.setup( 'django-bootstrap-form', 'django-stronghold', 'psutil', + 'python-apt', 'python-augeas', 'requests', 'ruamel.yaml',