示例#1
0
    def load(self):
        output.section("Preparing")

        output.step("main",
                    "Loading environment `{}`...".format(self.environment))

        self.environment = Environment(self.environment, self.timeout,
                                       self.platform)
        self.environment.deployment = self
        self.environment.load()

        if self.jobs is not None:
            self.jobs = self.jobs
        elif self.environment.jobs is not None:
            self.jobs = int(self.environment.jobs)
        else:
            self.jobs = 1
        output.step("main", "Number of jobs: %s" % self.jobs, debug=True)

        # This is located here to avoid duplicating the verification check
        # when loading the repository on the remote environment object.
        output.step("main", "Verifying repository ...")
        self.environment.repository.verify()

        output.step("main", "Loading secrets ...")
        self.environment.load_secrets()
示例#2
0
def main(environment, platform, timeout, dirty, consistency_only, predict_only,
         jobs):
    output.backend = TerminalBackend()
    output.line(self_id())
    STEPS = ['load', 'connect', 'configure', 'deploy']
    if consistency_only:
        ACTION = "CONSISTENCY CHECK"
        STEPS.remove('deploy')
    elif predict_only:
        ACTION = "DEPLOYMENT PREDICTION"
    else:
        ACTION = "DEPLOYMENT"
    with locked(".batou-lock"):
        deployment = Deployment(environment, platform, timeout, dirty, jobs,
                                predict_only)
        environment = deployment.environment
        try:
            for step in STEPS:
                try:
                    getattr(deployment, step)()
                except Exception as e:
                    environment.exceptions.append(e)

                if not environment.exceptions:
                    continue

                # Note: There is a similar sorting / output routine in
                # remote_core __channelexec__. This is a bit of copy/paste
                # due to the way bootstrapping works
                environment.exceptions = list(
                    filter(
                        lambda e: not isinstance(e, SilentConfigurationError),
                        environment.exceptions))

                environment.exceptions.sort(
                    key=lambda x: getattr(x, 'sort_key', (-99,)))

                exception = ''
                for exception in environment.exceptions:
                    if isinstance(exception, ReportingException):
                        output.line('')
                        exception.report()
                    else:
                        output.line('')
                        output.error("Unexpected exception")
                        tb = traceback.TracebackException.from_exception(
                            exception)
                        for line in tb.format():
                            output.line('\t' + line.strip(), red=True)

                summary = "{} FAILED (during {})".format(ACTION, step)
                output.section(summary, red=True)

                notify(summary, str(exception))
                sys.exit(1)

        finally:
            deployment.disconnect()
        output.section("{} FINISHED".format(ACTION), green=True)
        notify("{} SUCCEEDED".format(ACTION), environment.name)
示例#3
0
文件: deploy.py 项目: frlan/batou
def main(environment, platform, timeout, dirty, fast, consistency_only,
         predict_only, reset):
    output.backend = TerminalBackend()
    output.line(self_id())
    if consistency_only:
        ACTION = 'CONSISTENCY CHECK'
    elif predict_only:
        ACTION = 'DEPLOYMENT PREDICTION'
    else:
        ACTION = 'DEPLOYMENT'
    with locked('.batou-lock'):
        try:
            deployment = Deployment(environment,
                                    platform,
                                    timeout,
                                    dirty,
                                    fast,
                                    predict_only,
                                    reset=reset)
            deployment.load()
            deployment.connect()
            deployment.configure()
            if not consistency_only:
                deployment.deploy()
            deployment.disconnect()
        except MissingEnvironment as e:
            e.report()
            output.section("{} FAILED".format(ACTION), red=True)
            notify(
                '{} FAILED'.format(ACTION),
                'Configuration for {} encountered an error.'.format(
                    environment))
            sys.exit(1)
        except ConfigurationError:
            output.section("{} FAILED".format(ACTION), red=True)
            notify(
                '{} FAILED'.format(ACTION),
                'Configuration for {} encountered an error.'.format(
                    environment))
            sys.exit(1)
        except DeploymentError as e:
            e.report()
            output.section("{} FAILED".format(ACTION), red=True)
            notify('{} FAILED'.format(ACTION),
                   '{} encountered an error.'.format(environment))
            sys.exit(1)
        except Exception:
            # An unexpected exception happened. Bad.
            output.error("Unexpected exception", exc_info=sys.exc_info())
            output.section("{} FAILED".format(ACTION), red=True)
            notify('{} FAILED'.format(ACTION),
                   'Encountered an unexpected exception.')
            sys.exit(1)
        else:
            output.section('{} FINISHED'.format(ACTION), green=True)
            notify('{} SUCCEEDED'.format(ACTION), environment)
示例#4
0
 def provision(self):
     if not self.environment.provisioners:
         return
     output.section("Provisioning hosts ...")
     for host in self.environment.hosts.values():
         if host.provisioner:
             output.step(
                 host.name, "Provisioning with `{}` provisioner. {}".format(
                     host.provisioner.name,
                     "(Rebuild)" if host.provisioner.rebuild else ""))
             host.provisioner.provision(host)
示例#5
0
文件: deploy.py 项目: frlan/batou
    def load(self):
        output.section("Preparing")

        output.step("main",
                    "Loading environment `{}`...".format(self.environment))

        self.environment = Environment(self.environment, self.timeout,
                                       self.platform)
        self.environment.deployment = self
        self.environment.load()

        # This is located here to avoid duplicating the verification check
        # when loading the repository on the remote environment object.
        output.step("main", "Verifying repository ...")
        self.environment.repository.verify()

        output.step("main", "Loading secrets ...")
        self.environment.load_secrets()
示例#6
0
    def deploy(self):
        # Wait for all connections to finish
        output.section("Waiting for remaining connections ...")
        [c.join() for c in self.connections]

        if self.predict_only:
            output.section("Predicting deployment actions")
        else:
            output.section("Deploying")

        # Pick a reference remote (the last we initialised) that will pass us
        # the order we should be deploying components in.
        reference_node = [
            h for h in list(self.environment.hosts.values()) if not h.ignore
        ][0]

        self.loop = asyncio.get_event_loop()
        self.taskpool = ThreadPoolExecutor(self.jobs)
        self.loop.set_default_executor(self.taskpool)
        self._launch_components(reference_node.root_dependencies())

        pending = asyncio.Task.all_tasks()
        while pending:
            self.loop.run_until_complete(asyncio.gather(*pending))
            pending = {t for t in asyncio.Task.all_tasks() if not t.done()}
示例#7
0
文件: deploy.py 项目: admdev8/batou
    def deploy(self):
        # Wait for all connections to finish
        output.section("Waiting for remaining connections ...")
        [c.join() for c in self.connections]

        if self.predict_only:
            output.section("Predicting deployment actions")
        else:
            output.section("Deploying")

        # Pick a reference remote (the last we initialised) that will pass us
        # the order we should be deploying components in.
        reference_node = [
            h for h in list(self.environment.hosts.values()) if not h.ignore
        ][0]

        self.loop = asyncio.get_event_loop()
        self.taskpool = ThreadPoolExecutor(self.jobs)
        self.loop.set_default_executor(self.taskpool)
        self._launch_components(reference_node.root_dependencies())

        # asyncio.Task.all_tasks was removed in Python 3.9
        # but the replacement asyncio.all_tasks is only available
        # for Python 3.7 and upwards
        # confer https://docs.python.org/3/whatsnew/3.7.html
        # and https://docs.python.org/3.9/whatsnew/3.9.html
        if sys.version_info < (3, 7):
            all_tasks = asyncio.Task.all_tasks
        else:
            all_tasks = asyncio.all_tasks
        get_pending = lambda: {t for t in all_tasks() if not t.done()}
        pending = get_pending()
        while pending:
            self.loop.run_until_complete(asyncio.gather(*pending))
            pending = get_pending()
示例#8
0
 def configure(self):
     output.section("Configuring model ...")
     self.connections[0].join()
示例#9
0
 def connect(self):
     output.section("Connecting ...")
     # Consume the connection iterator to establish remaining connections.
     self.connections = list(self._connections())
示例#10
0
文件: deploy.py 项目: admdev8/batou
def main(
    environment, platform, timeout, dirty, consistency_only, predict_only, jobs
):
    output.backend = TerminalBackend()
    output.line(self_id())
    if consistency_only:
        ACTION = "CONSISTENCY CHECK"
    elif predict_only:
        ACTION = "DEPLOYMENT PREDICTION"
    else:
        ACTION = "DEPLOYMENT"
    with locked(".batou-lock"):
        try:
            deployment = Deployment(
                environment, platform, timeout, dirty, jobs, predict_only
            )
            deployment.load()
            deployment.connect()
            deployment.configure()
            if not consistency_only:
                deployment.deploy()
            deployment.disconnect()
        except FileLockedError as e:
            output.error("File already locked: {}".format(e.filename))
            output.section("{} FAILED".format(ACTION), red=True)
            notify(
                "{} FAILED".format(ACTION),
                "File already locked: {}".format(e.filename),
            )
        except MissingEnvironment as e:
            e.report()
            output.section("{} FAILED".format(ACTION), red=True)
            notify(
                "{} FAILED".format(ACTION),
                "Configuration for {} encountered an error.".format(
                    environment
                ),
            )
            sys.exit(1)
        except ConfigurationError:
            output.section("{} FAILED".format(ACTION), red=True)
            notify(
                "{} FAILED".format(ACTION),
                "Configuration for {} encountered an error.".format(
                    environment
                ),
            )
            sys.exit(1)
        except DeploymentError as e:
            e.report()
            output.section("{} FAILED".format(ACTION), red=True)
            notify(
                "{} FAILED".format(ACTION),
                "{} encountered an error.".format(environment),
            )
            sys.exit(1)
        except Exception:
            # An unexpected exception happened. Bad.
            output.error("Unexpected exception", exc_info=sys.exc_info())
            output.section("{} FAILED".format(ACTION), red=True)
            notify(
                "{} FAILED".format(ACTION),
                "Encountered an unexpected exception.",
            )
            sys.exit(1)
        else:
            output.section("{} FINISHED".format(ACTION), green=True)
            notify("{} SUCCEEDED".format(ACTION), environment)
示例#11
0
 def summarize(self):
     output.section("Summary")
     for node in list(self.environment.hosts.values()):
         node.summarize()
示例#12
0
def output_migration_step(title: str, text: str) -> None:
    """Print the information of migration step in a formatted way."""
    output.section(title, red=True)
    output.line(textwrap.dedent(text).replace('\n', ' '))
    output.line('')