예제 #1
0
    def start(self,
              name,
              restart=False,
              skip_confirm=False,
              primary_log_path='workflow.log',
              fail_fast=False):
        """
        Start, resume, or restart an workflow based on its name.  If resuming, deletes failed tasks.

        :param str name: A name for the workflow.  Must be unique for this Cosmos session.
        :param bool restart: If True and the workflow exists, delete it first.
        :param bool skip_confirm: (If True, do not prompt the shell for input before deleting workflows or files.
        :param str primary_log_path: The path of the primary log to write to.  If None, does not write to a file.  Log information is always printed to stderr.
        :param bool fail_fast: If True, terminate the workflow the first time a Task fails.
        :param int default_max_attempts: The default maximum number of times to attempt a Task.

        Otherwise, run all Tasks except those downstream of a failure.
        :rtype Workflow:
        :returns: An Workflow instance.
        """
        from .Workflow import Workflow
        assert os.path.exists(
            os.getcwd()
        ), "The current working dir of this environment, %s, does not exist" % os.getcwd(
        )
        # output_dir = os.path.abspath(output_dir)
        # output_dir = output_dir if output_dir[-1] != '/' else output_dir[0:]  # remove trailing slash
        # prefix_dir = os.path.split(output_dir)[0]
        # assert os.path.exists(prefix_dir), '%s does not exist' % prefix_dir
        from ..util.helpers import mkdir

        # assert isinstance(primary_log_path, basestring) and len(primary_log_path) > 0, 'invalid parimary log path'
        if primary_log_path is not None and os.path.dirname(primary_log_path):
            mkdir(os.path.dirname(primary_log_path))

        session = self.session

        old_id = None
        if restart:
            wf = session.query(Workflow).filter_by(name=name).first()
            if wf:
                old_id = wf.id
                msg = 'Restarting %s.  Are you sure you want to delete the all sql records?' % wf
                if not skip_confirm and not confirm(msg):
                    raise SystemExit('Quitting')

                wf.delete(delete_files=False)
            else:
                if not skip_confirm and not confirm(
                        'Workflow with name %s does not exist, '
                        'but `restart` is set to True.  '
                        'Continue by starting a new Workflow?' % name):
                    raise SystemExit('Quitting')

        # resuming?
        wf = session.query(Workflow).filter_by(name=name).first()
        # msg = 'Workflow started, Cosmos v%s' % __version__
        if wf:
            # resuming.
            if not skip_confirm and not confirm(
                    'Resuming %s.  All non-successful jobs will be deleted, '
                    'then any new tasks in the graph will be added and executed.  '
                    'Are you sure?' % wf):
                raise SystemExit('Quitting')
            # assert ex.cwd == output_dir, 'cannot change the output_dir of an workflow being resumed.'

            wf.successful = False
            wf.finished_on = None
            wf.status = WorkflowStatus.resuming

            # if not os.path.exists(wf.output_dir):
            #     raise IOError('output_directory %s does not exist, cannot resume %s' % (wf.output_dir, wf))

            wf.log.info('Resuming %s' % wf)
            session.add(wf)
            failed_tasks = [
                t for s in wf.stages for t in s.tasks if not t.successful
            ]
            n = len(failed_tasks)
            if n:
                wf.log.info(
                    'Deleting %s unsuccessful task(s) from SQL database, delete_files=%s'
                    % (n, False))
                for t in failed_tasks:
                    session.delete(t)

            for stage in filter(lambda s: len(s.tasks) == 0, wf.stages):
                wf.log.info(
                    'Deleting stage %s, since it has 0 successful Tasks' %
                    stage)
                session.delete(stage)

        else:
            # start from scratch
            # if check_output_dir:
            #     assert not os.path.exists(output_dir), 'Workflow.output_dir `%s` already exists.' % (output_dir)

            wf = Workflow(id=old_id,
                          name=name,
                          manual_instantiation=False,
                          successful=False)
            # mkdir(output_dir)  # make it here so we can start logging to logfile
            session.add(wf)

        wf.info['last_cmd_executed'] = get_last_cmd_executed()
        wf.info['cwd'] = os.getcwd()
        wf.info['fail_fast'] = fail_fast
        wf.primary_log_path = primary_log_path

        wf.log.info('Committing SQL session...')
        session.commit()
        session.expunge_all()
        session.add(wf)
        wf.log.info('Execution Command: %s' % get_last_cmd_executed())

        wf.cosmos_app = self

        return wf
예제 #2
0
파일: Cosmos.py 프로젝트: LPM-HMS/COSMOS2
    def start(self, name, restart=False, skip_confirm=False, primary_log_path='workflow.log', fail_fast=False):
        """
        Start, resume, or restart an workflow based on its name.  If resuming, deletes failed tasks.

        :param str name: A name for the workflow.  Must be unique for this Cosmos session.
        :param bool restart: If True and the workflow exists, delete it first.
        :param bool skip_confirm: (If True, do not prompt the shell for input before deleting workflows or files.
        :param str primary_log_path: The path of the primary log to write to.  If None, does not write to a file.  Log information is always printed to stderr.
        :param bool fail_fast: If True, terminate the workflow the first time a Task fails.
        :param int default_max_attempts: The default maximum number of times to attempt a Task.

        Otherwise, run all Tasks except those downstream of a failure.
        :rtype Workflow:
        :returns: An Workflow instance.
        """
        from .Workflow import Workflow
        assert os.path.exists(
            os.getcwd()), "The current working dir of this environment, %s, does not exist" % os.getcwd()
        # output_dir = os.path.abspath(output_dir)
        # output_dir = output_dir if output_dir[-1] != '/' else output_dir[0:]  # remove trailing slash
        # prefix_dir = os.path.split(output_dir)[0]
        # assert os.path.exists(prefix_dir), '%s does not exist' % prefix_dir
        from ..util.helpers import mkdir

        # assert isinstance(primary_log_path, basestring) and len(primary_log_path) > 0, 'invalid parimary log path'
        if primary_log_path is not None and os.path.dirname(primary_log_path):
            mkdir(os.path.dirname(primary_log_path))

        session = self.session

        old_id = None
        if restart:
            wf = session.query(Workflow).filter_by(name=name).first()
            if wf:
                old_id = wf.id
                msg = 'Restarting %s.  Are you sure you want to delete the all sql records?' % wf
                if not skip_confirm and not confirm(msg):
                    raise SystemExit('Quitting')

                wf.delete(delete_files=False)
            else:
                if not skip_confirm and not confirm('Workflow with name %s does not exist, '
                                                    'but `restart` is set to True.  '
                                                    'Continue by starting a new Workflow?' % name):
                    raise SystemExit('Quitting')

        # resuming?
        wf = session.query(Workflow).filter_by(name=name).first()
        # msg = 'Workflow started, Cosmos v%s' % __version__
        if wf:
            # resuming.
            if not skip_confirm and not confirm('Resuming %s.  All non-successful jobs will be deleted, '
                                                'then any new tasks in the graph will be added and executed.  '
                                                'Are you sure?' % wf):
                raise SystemExit('Quitting')
            # assert ex.cwd == output_dir, 'cannot change the output_dir of an workflow being resumed.'

            wf.successful = False
            wf.finished_on = None
            wf.status = WorkflowStatus.resuming

            # if not os.path.exists(wf.output_dir):
            #     raise IOError('output_directory %s does not exist, cannot resume %s' % (wf.output_dir, wf))

            wf.log.info('Resuming %s' % wf)
            session.add(wf)
            failed_tasks = [t for s in wf.stages for t in s.tasks if not t.successful]
            n = len(failed_tasks)
            if n:
                wf.log.info('Deleting %s unsuccessful task(s) from SQL database, delete_files=%s' % (n, False))
                for t in failed_tasks:
                    session.delete(t)

            for stage in filter(lambda s: len(s.tasks) == 0, wf.stages):
                wf.log.info('Deleting stage %s, since it has 0 successful Tasks' % stage)
                session.delete(stage)

        else:
            # start from scratch
            # if check_output_dir:
            #     assert not os.path.exists(output_dir), 'Workflow.output_dir `%s` already exists.' % (output_dir)

            wf = Workflow(id=old_id, name=name, manual_instantiation=False, successful=False)
            # mkdir(output_dir)  # make it here so we can start logging to logfile
            session.add(wf)

        wf.info['last_cmd_executed'] = get_last_cmd_executed()
        wf.info['cwd'] = os.getcwd()
        wf.info['fail_fast'] = fail_fast
        wf.primary_log_path = primary_log_path

        wf.log.info('Committing SQL session...')
        session.commit()
        session.expunge_all()
        session.add(wf)
        wf.log.info('Execution Command: %s' % get_last_cmd_executed())

        wf.cosmos_app = self

        return wf