Exemple #1
0
    def run(self, config, args):
        cookbook = CookBook(config)
        failed = []
        p_name = args.package[0]

        store = PackagesStore(config)
        p = store.get_package(p_name)
        ordered_recipes = map(lambda x: cookbook.get_recipe(x),
                              p.recipes_dependencies())

        for recipe in ordered_recipes:
            if cookbook.recipe_needs_build(recipe.name):
                raise CommandError(
                    _("Recipe %s is not built yet" % recipe.name))

        for recipe in ordered_recipes:
            # call step function
            stepfunc = None
            try:
                stepfunc = getattr(recipe, 'check')
            except:
                m.message('%s has no check step, skipped' % recipe.name)

            if stepfunc:
                try:
                    m.message('Running checks for recipe %s' % recipe.name)
                    stepfunc()
                except Exception as ex:
                    failed.append(recipe.name)
                    m.warning(_("%s checks failed: %s") % (recipe.name, ex))
        if failed:
            raise CommandError(
                _("Error running %s checks on:\n    " + "\n    ".join(failed))
                % p_name)
Exemple #2
0
def new_call(cmd, cmd_dir=None, fail=True, logfile=None, env=None):
    cmd = _cmd_string_to_array(cmd, env)
    if logfile:
        logfile.write('Running command {!r}\n'.format(cmd))
        logfile.flush()
    try:
        subprocess.check_call(cmd,
                              cwd=cmd_dir,
                              env=env,
                              stdout=logfile,
                              stderr=subprocess.STDOUT)
    except SUBPROCESS_EXCEPTIONS as e:
        returncode = getattr(e, 'returncode', -1)
        if not fail:
            stream = logfile or sys.stderr
            if isinstance(e, FileNotFoundError):
                stream.write('{}: file not found\n'.format(cmd[0]))
            if isinstance(e, PermissionError):
                stream.write('{!r}: permission error\n'.format(cmd))
            return returncode
        msg = ''
        if logfile:
            msg = 'Output in logfile {}'.format(logfile.name)
        raise CommandError(msg, cmd, returncode)
    return 0
Exemple #3
0
async def async_call(cmd,
                     cmd_dir='.',
                     fail=True,
                     logfile=None,
                     cpu_bound=True,
                     env=None):
    '''
    Run a shell command

    @param cmd: the command to run
    @type cmd: str
    @param cmd_dir: directory where the command will be run
    @param cmd_dir: str
    '''
    global CPU_BOUND_SEMAPHORE, NON_CPU_BOUND_SEMAPHORE
    semaphore = CPU_BOUND_SEMAPHORE if cpu_bound else NON_CPU_BOUND_SEMAPHORE

    async with semaphore:
        cmd = _cmd_string_to_array(cmd, env)

        if logfile is None:
            stream = None
        else:
            logfile.write("Running command '%s'\n" %
                          ' '.join([shlex.quote(c) for c in cmd]))
            logfile.flush()
            stream = logfile

        if DRY_RUN:
            # write to sdterr so it's filtered more easilly
            m.error("cd %s && %s && cd %s" % (cmd_dir, cmd, os.getcwd()))
            return

        env = os.environ.copy() if env is None else env.copy()
        # Force python scripts to print their output on newlines instead
        # of on exit. Ensures that we get continuous output in log files.
        env['PYTHONUNBUFFERED'] = '1'
        proc = await asyncio.create_subprocess_exec(*cmd,
                                                    cwd=cmd_dir,
                                                    stderr=subprocess.STDOUT,
                                                    stdout=stream,
                                                    stdin=subprocess.DEVNULL,
                                                    env=env)
        await proc.wait()
        if proc.returncode != 0 and fail:
            msg = ''
            if stream:
                msg = 'Output in logfile {}'.format(logfile.name)
            raise CommandError(msg, cmd, proc.returncode)

        return proc.returncode
Exemple #4
0
async def async_call_output(cmd,
                            cmd_dir=None,
                            logfile=None,
                            cpu_bound=True,
                            env=None):
    '''
    Run a shell command and get the output

    @param cmd: the command to run
    @type cmd: str
    @param cmd_dir: directory where the command will be run
    @param cmd_dir: str
    '''
    global CPU_BOUND_SEMAPHORE, NON_CPU_BOUND_SEMAPHORE
    semaphore = CPU_BOUND_SEMAPHORE if cpu_bound else NON_CPU_BOUND_SEMAPHORE

    async with semaphore:
        cmd = _cmd_string_to_array(cmd, env)

        if PLATFORM == Platform.WINDOWS:
            import cerbero.hacks
            # On Windows, create_subprocess_exec with a PIPE fails while creating
            # a named pipe using tempfile.mktemp because we override os.path.join
            # to use / on Windows. Override the tempfile module's reference to the
            # original implementation, then change it back later so it doesn't leak.
            # XXX: Get rid of this once we move to Path.as_posix() everywhere
            tempfile._os.path.join = cerbero.hacks.oldjoin
            # The tempdir is derived from TMP and TEMP which use / as the path
            # separator, which fails for the same reason as above. Ensure that \ is
            # used instead.
            tempfile.tempdir = str(PurePath(tempfile.gettempdir()))

        proc = await asyncio.create_subprocess_exec(*cmd,
                                                    cwd=cmd_dir,
                                                    stdout=subprocess.PIPE,
                                                    stderr=logfile,
                                                    stdin=subprocess.DEVNULL,
                                                    env=env)
        (output, unused_err) = await proc.communicate()

        if PLATFORM == Platform.WINDOWS:
            os.path.join = cerbero.hacks.join

        if sys.stdout.encoding:
            output = output.decode(sys.stdout.encoding, errors='replace')

        if proc.returncode != 0:
            raise CommandError(output, cmd, proc.returncode)

        return output
Exemple #5
0
class CheckPackage(Command):
    doc = N_('Run checks on a given package')
    name = 'checkpackage'

    def __init__(self):
        Command.__init__(self, [
            ArgparseArgument('package',
                             nargs=1,
                             help=_('name of the package to run checks on')),
        ])

    def run(self, config, args):
        cookbook = CookBook(config)
        failed = []
        p_name = args.package[0]

        store = PackagesStore(config)
        p = store.get_package(p_name)
        ordered_recipes = map(lambda x: cookbook.get_recipe(x),
                              p.recipes_dependencies())

        for recipe in ordered_recipes:
            if cookbook.recipe_needs_build(recipe.name):
                raise CommandError(
                    _("Recipe %s is not built yet" % recipe.name))

        for recipe in ordered_recipes:
            # call step function
            stepfunc = None
            try:
                stepfunc = getattr(recipe, 'check')
            except:
                m.message('%s has no check step, skipped' % recipe.name)

            if stepfunc:
                try:
                    m.message('Running checks for recipe %s' % recipe.name)
                    stepfunc()
                except Exception, ex:
                    failed.append(recipe.name)
                    m.warning(_("%s checks failed: %s") % (recipe.name, ex))
        if failed:
            raise CommandError(
                _("Error running %s checks on:\n    " + "\n    ".join(failed))
                % p_name)
Exemple #6
0
def check_output(cmd,
                 cmd_dir=None,
                 fail=True,
                 logfile=None,
                 env=None,
                 quiet=False):
    cmd = _cmd_string_to_array(cmd, env)
    stderr = logfile
    if quiet and not logfile:
        stderr = subprocess.DEVNULL

    try:
        o = subprocess.check_output(cmd, cwd=cmd_dir, env=env, stderr=stderr)
    except SUBPROCESS_EXCEPTIONS as e:
        msg = getattr(e, 'output', '')
        if not fail:
            return msg
        if logfile:
            msg += '\nstderr in logfile {}'.format(logfile.name)
        raise CommandError(msg, cmd, getattr(e, 'returncode', -1))

    if sys.stdout.encoding:
        o = o.decode(sys.stdout.encoding, errors='replace')
    return o
Exemple #7
0
def call(cmd, cmd_dir='.', fail=True, verbose=False, logfile=None, env=None):
    '''
    Run a shell command
    DEPRECATED: Use new_call and a cmd array wherever possible

    @param cmd: the command to run
    @type cmd: str
    @param cmd_dir: directory where the command will be run
    @param cmd_dir: str
    @param fail: whether or not to raise an exception if the command fails
    @type fail: bool
    '''
    try:
        if logfile is None:
            if verbose:
                m.message("Running command '%s'" % cmd)
            stream = None
        else:
            logfile.write("Running command '%s'\n" % cmd)
            logfile.flush()
            stream = logfile
        shell = True
        if PLATFORM == Platform.WINDOWS:
            # windows do not understand ./
            if cmd.startswith('./'):
                cmd = cmd[2:]
            # run all processes through sh.exe to get scripts working
            cmd = '%s "%s"' % ('sh -c', cmd)
            # fix paths with backslashes
            cmd = _fix_mingw_cmd(cmd)
            # Disable shell which uses cmd.exe
            shell = False
        if DRY_RUN:
            # write to sdterr so it's filtered more easilly
            m.error("cd %s && %s && cd %s" % (cmd_dir, cmd, os.getcwd()))
            ret = 0
        else:
            if env is not None:
                env = env.copy()
            else:
                env = os.environ.copy()

            # Force python scripts to print their output on newlines instead
            # of on exit. Ensures that we get continuous output in log files.
            env['PYTHONUNBUFFERED'] = '1'
            ret = subprocess.check_call(cmd,
                                        cwd=cmd_dir,
                                        bufsize=1,
                                        stderr=subprocess.STDOUT,
                                        stdout=stream,
                                        universal_newlines=True,
                                        env=env,
                                        shell=shell)
    except SUBPROCESS_EXCEPTIONS as e:
        if fail:
            msg = ''
            if stream:
                msg = 'Output in logfile {}'.format(logfile.name)
            raise CommandError(msg, cmd, getattr(e, 'returncode', -1))
        else:
            ret = 0
    return ret