Exemplo n.º 1
0
def preview_apps(self, apps=None):
    """install one or more apps to the base. If app is defined, only
       install app specified. Otherwise, install all found in config.
    """
    if apps in [None, []]:
        apps = self.apps()

    if not isinstance(apps, list):
        apps = [apps]

    for app in apps:

        # We must have the app defined in the config
        if app not in self._config["apps"]:
            bot.exit("Cannot find app %s in config." % app)

        # Make directories
        bot.newline()
        settings = self._init_app_preview(app)

        # Get the app configuration
        config = self.app(app)

        # Handle environment, runscript, labels
        self._preview_runscript(app, settings, config)
        self._preview_environment(app, settings, config)
        self._preview_labels(app, settings, config)
        self._preview_commands(app, settings, config)
        self._preview_files(app, settings, config)
        self._preview_recipe(app, settings, config)
        self._preview_test(app, settings, config)
        bot.newline()
Exemplo n.º 2
0
def run(self, app=None, args=None):
    '''run an app. This means the following:

    1. Check that the app is valid for the client. Don't proceed otherwise
    2. Set the client app to be active
    3. update the environment to indicate the app is active
    4. set the entry point and entry folder relevant to the app

    Parameters
    ==========
    app: the name of the scif app to run
    args: a list of one or more additional arguments to pass to runscript

    '''
    # Cut out early if the app doesn't have a runscript
    config = self.app(app)
    if 'apprun' not in config:
        bot.exit('%s does not have a runscript.' % app)

    self.activate(app, args=args)  # checks for existence
    # sets _active to app's name
    # updates environment
    # sets entrypoint
    # sets entryfolder

    return self._exec(app)
Exemplo n.º 3
0
def set_base(self, base='/', writable=True):
    ''' set the base (the root where to create /scif) and determine if
        it is writable

        Parameters
        ==========
        base: the full path to the root folder to create /scif
    '''
    # The user is likely to give path to scif (should still work)
    base = base.strip('scif')

    if not os.path.exists(base):
        bot.exit('%s does not exist!' % base)

    base = "/%s" % os.path.abspath(base).strip('/')
    self._base = os.path.join(base, 'scif')
    self.path_apps = '%s/apps' % self._base
    self.path_data = '%s/data' % self._base

    # Update the environment
    self.add_env('SCIF_DATA', self.path_data)
    self.add_env('SCIF_APPS', self.path_apps)

    # Check if it's writable
    if writable is True:
        if not os.access(base, os.W_OK):
            bot.exit('%s is not writable.' % base)
Exemplo n.º 4
0
def set_base(self, base="/", writable=True):
    """ set the base (the root where to create /scif) and determine if
        it is writable

        Parameters
        ==========
        base: the full path to the root folder to create /scif
    """
    # The user is likely to give path to scif (should still work)
    base = base.strip("scif")

    if not os.path.exists(base):
        bot.exit("%s does not exist!" % base)

    base = "/%s" % os.path.abspath(base).strip("/")
    self._base = os.path.join(base, "scif")
    self.path_apps = "%s/apps" % self._base
    self.path_data = "%s/data" % self._base

    # Update the environment
    self.add_env("SCIF_DATA", self.path_data)
    self.add_env("SCIF_APPS", self.path_apps)

    # Check if it's writable
    if writable is True:
        if not os.access(base, os.W_OK):
            bot.exit("%s is not writable." % base)
Exemplo n.º 5
0
def install_commands(self, app, settings, config):
    """install will finally, issue commands to install the app.

       Parameters
       ==========
       app should be the name of the app, for lookup in config['apps']
       settings: the output of _init_app(), a dictionary of environment vars
       config: should be the config for the app obtained with self.app(app)

    """
    if "appinstall" in config:

        # Change directory so the APP is $PWD
        pwd = os.getcwd()
        os.chdir(settings["approot"])

        # Set strict mode to ensure exit on error
        command = ["set -e"] + config["appinstall"]

        # issue install commands
        cmd = "\n".join(command)
        bot.info("+ " + "appinstall ".ljust(5) + app)
        retval = os.system(cmd)
        if retval != 0:
            bot.exit("Return value %s for install of %s" % (retval, app))

        # Go back to previous location
        os.chdir(pwd)
Exemplo n.º 6
0
def mkdir_p(path):
    """mkdir_p attempts to get the same functionality as mkdir -p
    :param path: the path to create.
    """
    try:
        os.makedirs(path)
    except OSError as e:
        if e.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else:
            bot.exit("Error creating path %s, exiting." % path)
Exemplo n.º 7
0
def preview_base(self):
    ''' preview basic scif structure at the base for apps and metadata

        Parameters
        ==========
        base: the full path to the root folder to create /scif
    '''
    if not hasattr(self, '_base'):
        bot.exit('Please set the base before preview.')

    bot.custom(prefix='[base] %s' % self._base, color='CYAN')
    bot.custom(prefix='[apps] %s' % self.path_apps, color='CYAN')
    bot.custom(prefix='[data] %s\n' % self.path_data, color='CYAN')
Exemplo n.º 8
0
def preview_base(self):
    """ preview basic scif structure at the base for apps and metadata

        Parameters
        ==========
        base: the full path to the root folder to create /scif
    """
    if not hasattr(self, "_base"):
        bot.exit("Please set the base before preview.")

    bot.custom(prefix="[base] %s" % self._base, color="CYAN")
    bot.custom(prefix="[apps] %s" % self.path_apps, color="CYAN")
    bot.custom(prefix="[data] %s\n" % self.path_data, color="CYAN")
Exemplo n.º 9
0
def install_base(self):
    ''' create basic scif structure at the base for apps and metadata

        Parameters
        ==========
        base: the full path to the root folder to create /scif
    '''
    if not hasattr(self, '_base'):
        bot.exit('Please set the base before installing to it.')

    bot.info('Installing base at %s' % self._base)

    mkdir_p(self.path_apps)
    mkdir_p(self.path_data)
Exemplo n.º 10
0
def install_base(self):
    """ create basic scif structure at the base for apps and metadata

        Parameters
        ==========
        base: the full path to the root folder to create /scif
    """
    if not hasattr(self, "_base"):
        bot.exit("Please set the base before installing to it.")

    bot.info("Installing base at %s" % self._base)

    mkdir_p(self.path_apps)
    mkdir_p(self.path_data)
Exemplo n.º 11
0
def main(args, parser, subparser):

    from scif.main import ScifRecipe
    apps = args.recipe

    if len(apps) > 0:
        recipe = apps.pop(0)

        if not os.path.exists(recipe):
            bot.exit("Cannot find recipe file %s" % recipe)

        client = ScifRecipe(recipe, writable=False)

        # Preview the entire recipe, or the apps chosen
        client.preview(apps)

    else:
        bot.info('You must provide a recipe file to preview!')
Exemplo n.º 12
0
def getenv(variable_key, default=None, required=False, silent=True):
    """ getenv will attempt to get an environment variable. If the variable
        is not found, None is returned.

        Paramters
        =========
        variable_key: the variable name
        required: exit with error if not found
        silent: Do not print debugging information for variable
    """
    variable = os.environ.get(variable_key, default)
    if variable is None and required:
        bot.exit("Cannot find environment variable %s, exiting." %
                 variable_key)

    if not silent and variable is not None:
        bot.verbose("%s found as %s" % (variable_key, variable))

    return variable
Exemplo n.º 13
0
def run_command(self, cmd, spinner=True, quiet=True):
    """run_command will run a command (a list) and wrap in a spinner. A 
       result (dict) with message and return code is returned. If the
       return value is not 0, an error is issed and we exit
    """
    if spinner is True:
        bot.spinner.start()

    result = run_cmd(cmd, quiet=quiet)

    if spinner is True:
        bot.spinner.stop()

    retval = result["return_code"]

    # Beep boop, error!
    if retval != 0:
        bot.exit("Return code %s" % retval, retval)

    return result
Exemplo n.º 14
0
def main(args, parser, subparser):

    from scif.main import ScifRecipe
    apps = args.recipe

    if len(apps) == 0:
        bot.exit("You must provide a recipe (.scif) file to install.")

    recipe = apps.pop(0)

    if not os.path.exists(recipe):
        bot.exit("Cannot find recipe file %s" % recipe)

    if len(apps) == 0:
        apps = None

    client = ScifRecipe(path=recipe)  # writable is True

    # Preview the entire recipe, or the apps chosen
    client.install(apps)
Exemplo n.º 15
0
def install_apps(self, apps=None):
    """install one or more apps to the base. If app is defined, only
       install app specified. Otherwise, install all found in config.
    """
    if apps in [None, ""]:
        apps = self.apps()

    if not isinstance(apps, list):
        apps = [apps]

    if len(apps) == 0:
        bot.warning("No apps to install. Load a recipe or base with .load()")

    for app in apps:

        # We must have the app defined in the config
        if app not in self._config["apps"]:
            bot.exit("Cannot find app %s in config." % app)

        # Make directories
        settings = self._init_app(app)

        # Get the app configuration
        config = self.app(app)

        # Get the app environment and export for install
        self.get_appenv(app, isolated=False, update=True)
        self.export_env(ps1=False)

        # Handle environment, runscript, labels
        self._install_runscript(app, settings, config)
        self._install_environment(app, settings, config)
        self._install_help(app, settings, config)
        self._install_labels(app, settings, config)
        self._install_files(app, settings, config)
        self._install_commands(app, settings, config)
        self._install_recipe(app, settings, config)
        self._install_test(app, settings, config)

        # After we install, in case interactive, deactivate last app
        self.deactivate(app)
Exemplo n.º 16
0
def add_section(config, section, name=None, global_section="apps"):
    ''' add section will add a section (and optionally)
        section name to a config

        Parameters
        ==========
        config: the config (dict) parsed thus far
        section: the section type (e.g., appinstall)
        name: an optional name, added as a level (e.g., google-drive)

        Resulting data structure is:

            config['registry']['apprun']
            config[name][section]

    '''

    if section is None:
        bot.exit('You must define a section (e.g. %appenv) before any action.')

    if section not in sections:
        bot.exit("%s is not a valid section." % section)

    # Add the global section, if doesn't exist
    if global_section not in config:
        config[global_section] = OrderedDict()

    if name is not None:
        if name not in config[global_section]:
            config[global_section][name] = OrderedDict()

        if section not in config[global_section][name]:
            config[global_section][name][section] = []
            bot.debug("Adding section %s %s" % (name, section))

    return config
Exemplo n.º 17
0
def _exec(self, app=None, interactive=False, exit=False):
    """exec is the underlying driver of both run and exec, taking a final
       SCIF and executing the command for the user.

       This function is called via self._exec, and the expectation is that
       self.run or self.exec has been called first to prepare the environment
       and SCIF settings.

       If a user wants to preserve an environment variable from the console
       it can be referenced with [e], for example $SCIF_DATA --> [e]SCIF_DATA

       Parameters
       ==========
       app: the name of the application to execute a command to
       interactive: if True, us os.system directly
       exit: exit with return code from command (for test)

    """

    name = ""
    if app is not None and app in self.apps():
        name = "[%s] " % app

    # If the entry folder still not set, we don't have an app
    if self._entry_folder is None:
        self._entry_folder = SCIF_BASE

    # Change directory to the relevant place
    os.chdir(self._entry_folder)

    # export environment
    runtime_environ = self.export_env()

    # Execv to the entrypoint
    executable = which(self._entry_point[0])

    # Exit if command not found
    args = ""
    if executable is None:
        bot.exit("%s not found." % self._entry_point[0])

    if len(self._entry_point) > 1:
        if exit is False:
            args = " ".join(self._entry_point[1:])
        else:
            args = self._entry_point[1:]

    # Are we executing a command as a string?
    if not isinstance(args, list):
        cmd = "%s %s" % (executable, args)
        bot.info("%sexecuting %s" % (name, cmd))

    # or a list with execv?
    else:
        bot.info("%sexecuting %s %s" % (name, executable, " ".join(args)))

    # Return output to console
    loc = locale.getdefaultlocale()[1]

    # A shell will run the command
    if interactive is True:

        # Will exit with error, if happens, otherwise exit with 0
        if exit is True:
            result = self._run_command(cmd=[executable] + args,
                                       spinner=False,
                                       quiet=self.quiet)
            sys.exit(result["return_code"])
        else:
            os.system("".join(cmd))

    else:
        for line in os.popen(cmd):
            try:
                print(line.rstrip())
            except:
                print(line.rstrip().encode(loc))