예제 #1
0
        def cleanup_broker():
            # @Dave: This is maybe too brute force and there is maybe a better pattern...
            connect_str = "-q -H %s -P %s -u %s -p %s -V %s" % (CFG.get_safe('server.amqp_priv.host', CFG.get_safe('server.amqp.host', 'localhost')),
                                                                   CFG.get_safe('container.exchange.management.port', '55672'),
                                                                   CFG.get_safe('container.exchange.management.username', 'guest'),
                                                                   CFG.get_safe('container.exchange.management.password', 'guest'),
                                                                   '/')

            from putil.rabbithelper import clean_by_sysname
            clean_by_sysname(connect_str, get_sys_name())
예제 #2
0
파일: pycc.py 프로젝트: ooici/pyon
    def prepare_container():
        """
        Walks through pyon initialization in a deterministic way and initializes Container.
        In particular make sure configuration is loaded in correct order and
        pycc startup arguments are considered.
        """
        import threading

        threading.current_thread().name = "CC-Main"

        # SIDE EFFECT: The import triggers static initializers: Monkey patching, setting pyon defaults
        import pyon

        from pyon.core import bootstrap, config

        # Set global testing flag to False. We are running as capability container, because
        # we started through the pycc program.
        bootstrap.testing = False

        # Set sysname if provided in startup argument
        if opts.sysname:
            bootstrap.set_sys_name(opts.sysname)
        # Trigger any initializing default logic in get_sys_name
        bootstrap.get_sys_name()

        command_line_config = kwargs

        # This holds the minimal configuration used to bootstrap pycc and pyon and connect to datastores.
        bootstrap_config = None

        # This holds the new CFG object for pyon. Build it up in proper sequence and conditions.
        pyon_config = config.read_standard_configuration()  # Initial pyon.yml + pyon.local.yml

        # Load config override if provided. Supports variants literal and list of paths
        config_override = None
        if opts.config:
            if "{" in opts.config:
                # Variant 1: Dict of config values
                try:
                    eval_value = ast.literal_eval(opts.config)
                    config_override = eval_value
                except ValueError:
                    raise Exception("Value error in config arg '%s'" % opts.config)
            else:
                # Variant 2: List of paths
                from pyon.util.config import Config

                config_override = Config([opts.config]).data

        # Determine bootstrap_config
        if opts.config_from_directory:
            # Load minimal bootstrap config if option "config_from_directory"
            bootstrap_config = config.read_local_configuration(["res/config/pyon_min_boot.yml"])
            config.apply_local_configuration(bootstrap_config, pyon.DEFAULT_LOCAL_CONFIG_PATHS)
            config.apply_configuration(bootstrap_config, config_override)
            config.apply_configuration(bootstrap_config, command_line_config)
            print "pycc: config_from_directory=True. Minimal bootstrap configuration:", bootstrap_config
        else:
            # Otherwise: Set to standard set of local config files plus command line overrides
            bootstrap_config = deepcopy(pyon_config)
            config.apply_configuration(bootstrap_config, config_override)
            config.apply_configuration(bootstrap_config, command_line_config)

        # Override sysname from config file or command line
        if not opts.sysname and bootstrap_config.get_safe("system.name", None):
            new_sysname = bootstrap_config.get_safe("system.name")
            bootstrap.set_sys_name(new_sysname)

        # Delete sysname datastores if option "force_clean" is set
        if opts.force_clean:
            from pyon.datastore import clear_couch_util

            print "pycc: force_clean=True. DROP DATASTORES for sysname=%s" % bootstrap.get_sys_name()
            clear_couch_util.clear_couch(
                bootstrap_config, prefix=bootstrap.get_sys_name(), sysname=bootstrap.get_sys_name()
            )
            pyon_config.container.filesystem.force_clean = True

        from pyon.core.interfaces.interfaces import InterfaceAdmin

        iadm = InterfaceAdmin(bootstrap.get_sys_name(), config=bootstrap_config)

        # If auto_bootstrap, load config and interfaces into directory
        # Note: this is idempotent and will not alter anything if this is not the first container to run
        if bootstrap_config.system.auto_bootstrap:
            print "pycc: auto_bootstrap=True."
            stored_config = deepcopy(pyon_config)
            config.apply_configuration(stored_config, config_override)
            config.apply_configuration(stored_config, command_line_config)
            iadm.create_core_datastores()
            iadm.store_config(stored_config)

        # Determine the final pyon_config
        # - Start from standard config already set (pyon.yml + local YML files)
        # - Optionally load config from directory
        if opts.config_from_directory:
            config.apply_remote_config(bootstrap_cfg=bootstrap_config, system_cfg=pyon_config)
        # - Apply container profile specific config
        config.apply_profile_configuration(pyon_config, bootstrap_config)
        # - Reapply pyon.local.yml here again for good measure
        config.apply_local_configuration(pyon_config, pyon.DEFAULT_LOCAL_CONFIG_PATHS)
        # - Last apply any separate command line config overrides
        config.apply_configuration(pyon_config, config_override)
        config.apply_configuration(pyon_config, command_line_config)

        # Also set the immediate flag, but only if specified - it is an override
        if opts.immediate:
            from pyon.util.containers import dict_merge

            dict_merge(pyon_config, {"system": {"immediate": True}}, True)

        # Bootstrap pyon's core. Load configuration etc.
        bootstrap.bootstrap_pyon(pyon_cfg=pyon_config)

        # Delete any queues/exchanges owned by sysname if option "broker_clean" is set
        if opts.broker_clean:
            print "pycc: broker_clean=True, sysname:", bootstrap.get_sys_name()

            # build connect str
            connect_str = "-q -H %s -P %s -u %s -p %s -V %s" % (
                pyon_config.get_safe("server.amqp_priv.host", pyon_config.get_safe("server.amqp.host", "localhost")),
                pyon_config.get_safe("container.exchange.management.port", "55672"),
                pyon_config.get_safe("container.exchange.management.username", "guest"),
                pyon_config.get_safe("container.exchange.management.password", "guest"),
                "/",
            )

            from putil.rabbithelper import clean_by_sysname

            deleted_exchanges, deleted_queues = clean_by_sysname(connect_str, bootstrap.get_sys_name())
            print "      exchanges deleted (%s): %s" % (len(deleted_exchanges), ",".join(deleted_exchanges))
            print "         queues deleted (%s): %s" % (len(deleted_queues), ",".join(deleted_queues))

        if opts.force_clean:
            path = os.path.join(pyon_config.get_safe("container.filesystem.root", "/tmp/ion"), bootstrap.get_sys_name())
            print "force_clean: Removing", path
            FileSystem._clean(pyon_config)

        # Auto-bootstrap interfaces
        if bootstrap_config.system.auto_bootstrap:
            iadm.store_interfaces(idempotent=True)

        iadm.close()

        if opts.no_container:
            print "pycc: no_container=True. Stopping here."
            return None

        # Create the container instance
        from pyon.container.cc import Container

        container = Container(*args, **command_line_config)

        return container
예제 #3
0
파일: pycc.py 프로젝트: pkediyal/pyon
    def prepare_container():
        """
        Walks through pyon initialization in a deterministic way and initializes Container.
        In particular make sure configuration is loaded in correct order and
        pycc startup arguments are considered.
        """
        import threading
        threading.current_thread().name = "CC-Main"

        # SIDE EFFECT: The import triggers static initializers: Monkey patching, setting pyon defaults
        import pyon

        from pyon.core import bootstrap, config

        # Set global testing flag to False. We are running as capability container. This is NO TEST.
        bootstrap.testing = False

        # Set sysname if provided in startup argument
        if opts.sysname:
            bootstrap.set_sys_name(opts.sysname)
        # Trigger any initializing default logic in get_sys_name
        bootstrap.get_sys_name()

        command_line_config = kwargs

        # This holds the minimal configuration used to bootstrap pycc and pyon and connect to datastores.
        bootstrap_config = None

        # This holds the new CFG object for pyon. Build it up in proper sequence and conditions.
        pyon_config = config.read_standard_configuration(
        )  # Initial pyon.yml + pyon.local.yml

        # Load config override if provided. Supports variants literal and list of paths
        config_override = None
        if opts.config:
            if '{' in opts.config:
                # Variant 1: Dict of config values
                try:
                    eval_value = ast.literal_eval(opts.config)
                    config_override = eval_value
                except ValueError:
                    raise Exception("Value error in config arg '%s'" %
                                    opts.config)
            else:
                # Variant 2: List of paths
                from pyon.util.config import Config
                config_override = Config([opts.config]).data

        # Determine bootstrap_config
        if opts.config_from_directory:
            # Load minimal bootstrap config if option "config_from_directory"
            bootstrap_config = config.read_local_configuration(
                ['res/config/pyon_min_boot.yml'])
            config.apply_local_configuration(bootstrap_config,
                                             pyon.DEFAULT_LOCAL_CONFIG_PATHS)
            config.apply_configuration(bootstrap_config, config_override)
            config.apply_configuration(bootstrap_config, command_line_config)
            print "pycc: config_from_directory=True. Minimal bootstrap configuration:", bootstrap_config
        else:
            # Otherwise: Set to standard set of local config files plus command line overrides
            bootstrap_config = deepcopy(pyon_config)
            config.apply_configuration(bootstrap_config, config_override)
            config.apply_configuration(bootstrap_config, command_line_config)

        # Override sysname from config file or command line
        if not opts.sysname and bootstrap_config.get_safe("system.name", None):
            new_sysname = bootstrap_config.get_safe("system.name")
            bootstrap.set_sys_name(new_sysname)

        # Delete sysname datastores if option "force_clean" is set
        if opts.force_clean:
            from pyon.datastore import clear_couch_util
            print "pycc: force_clean=True. DROP DATASTORES for sysname=%s" % bootstrap.get_sys_name(
            )
            clear_couch_util.clear_couch(bootstrap_config,
                                         prefix=bootstrap.get_sys_name())
            pyon_config.container.filesystem.force_clean = True

        from pyon.core.interfaces.interfaces import InterfaceAdmin
        iadm = InterfaceAdmin(bootstrap.get_sys_name(),
                              config=bootstrap_config)

        # If auto_bootstrap, load config and interfaces into directory
        # Note: this is idempotent and will not alter anything if this is not the first container to run
        if bootstrap_config.system.auto_bootstrap:
            print "pycc: auto_bootstrap=True."
            stored_config = deepcopy(pyon_config)
            config.apply_configuration(stored_config, config_override)
            config.apply_configuration(stored_config, command_line_config)
            iadm.create_core_datastores()
            iadm.store_config(stored_config)

        # Determine the final pyon_config
        # - Start from standard config already set (pyon.yml + local YML files)
        # - Optionally load config from directory
        if opts.config_from_directory:
            config.apply_remote_config(bootstrap_cfg=bootstrap_config,
                                       system_cfg=pyon_config)
            config.apply_local_configuration(
                pyon_config, pyon.DEFAULT_LOCAL_CONFIG_PATHS
            )  # apply pyon.local.yml again over top
        # - Last apply any separate command line config overrides
        config.apply_configuration(pyon_config, config_override)
        config.apply_configuration(pyon_config, command_line_config)

        # Also set the immediate flag, but only if specified - it is an override
        if opts.immediate:
            from pyon.util.containers import dict_merge
            dict_merge(pyon_config, {'system': {'immediate': True}}, True)

        # Bootstrap pyon's core. Load configuration etc.
        bootstrap.bootstrap_pyon(pyon_cfg=pyon_config)

        # Delete any queues/exchanges owned by sysname if option "broker_clean" is set
        if opts.broker_clean:
            print "pycc: broker_clean=True, sysname:", bootstrap.get_sys_name()

            # build connect str
            connect_str = "-q -H %s -P 55672 -u %s -p %s -V %s" % (
                pyon_config.get_safe(
                    'server.amqp_priv.host',
                    pyon_config.get_safe('server.amqp.host', 'localhost')),
                pyon_config.get_safe('container.exchange.management.username',
                                     'guest'),
                pyon_config.get_safe('container.exchange.management.password',
                                     'guest'), '/')

            from putil.rabbithelper import clean_by_sysname
            deleted_exchanges, deleted_queues = clean_by_sysname(
                connect_str, bootstrap.get_sys_name())
            print "      exchanges deleted (%s): %s" % (
                len(deleted_exchanges), ",".join(deleted_exchanges))
            print "         queues deleted (%s): %s" % (
                len(deleted_queues), ",".join(deleted_queues))

        # Auto-bootstrap interfaces
        if bootstrap_config.system.auto_bootstrap:
            iadm.store_interfaces(idempotent=True)

        iadm.close()

        if opts.no_container:
            print "pycc: no_container=True. Stopping here."
            return None

        # Create the container instance
        from pyon.container.cc import Container
        container = Container(*args, **command_line_config)

        return container
예제 #4
0
    def begin(self):
        """Called before any tests are collected or run. Use this to
        perform any setup needed before testing begins.
        """
        # Make sure we initialize pyon before anything in this plugin executes
        from pyon.core import bootstrap
        if not bootstrap.pyon_initialized:
            bootstrap.bootstrap_pyon()

        try:
            from pyon.public import get_sys_name, CFG
            self.sysname = get_sys_name()

            # Clean exchanges and system queues out there
            try:
                connect_str = '-H %s -P 55672 -u %s -p %s -V %s' % (CFG.server.amqp.host,
                                                                    CFG.server.amqp.username,
                                                                    CFG.server.amqp.password,
                                                                    CFG.server.amqp.vhost)

                deleted_exchanges, deleted_queues = clean_by_sysname(connect_str, self.sysname)

                debug.write('Deleted exchanges:\n%s \n' % '\n'.join(deleted_exchanges))
                debug.write('Deleted queues:\n%s \n' % '\n'.join(deleted_queues))

            except Exception as e:
                pass

            # Force datastore loader to use the same sysname
            from pyon.datastore.datastore_admin import DatastoreAdmin
            self.datastore_admin = DatastoreAdmin(config=CFG)

            self.datastore_admin.clear_datastore(prefix=self.sysname)

            def die(signum, frame):
                # For whatever reason, the parent doesn't die some times
                # when getting KeyboardInterrupt.  Hence this signal
                # handler.

                # Signal is pass through. The child pycc gets
                # its own KeyboardInterrupt and will shut down accordingly.
                debug.write('Received Keyboard Interrupt. Exiting now.\n')
                os._exit(9)

            signal.signal(signal.SIGINT, die)

            def no_zombie(signum, frame):
                # Debug to figure out who's dying
                debug.write('SIGCHLD received\n')
                stack = []
                while frame:
                    stack.append(frame)
                    frame =frame.f_back
                stack.reverse()
                for frame in stack:
                    debug.write('Frame %s in %s at line %s\n' %
                            (frame.f_code.co_name,
                                frame.f_code.co_filename, frame.f_lineno))
                debug.write('Child is dead...Clean up now so there is no zombie\n')
                (pid, status) = os.wait()
                exitstatus, signum = status & 0xff, (status & 0xff00) >> 8
                debug.write('Child pid %d with exit status %d and signum %d\n' % (pid, exitstatus, signum))
            # Could be dangerous.  Comment this out.
            # signal.signal(signal.SIGCHLD, no_zombie)

            def container_started_cb(signum, frame):
                """Callback when child pycc service is ready"""
                self.container_started = True

            signal.signal(signal.SIGUSR1, container_started_cb)

            # Make sure the pycc process has the same sysname as the nose
            ccargs = ['bin/pycc', '-o', '--noshell', '-sp', '--sysname=%s' % self.sysname,
                    '--logcfg=res/config/logging.pycc.yml',
                    '--rel=%s' % self.rel,
                    "--config={'system': {'auto_bootstrap': True}}"]
            debug.write('Starting cc process: %s\n' % ' '.join(ccargs))
            newenv = os.environ.copy()
            po = subprocess.Popen(ccargs, env=newenv, close_fds=True)
            self.ccs.append(po)

            # Wait for container to be ready
            while not self.container_started:
                time.sleep(0.2)
            debug.write('Child container is ready...\n')

            # Dump datastore
            self.datastore_admin.dump_datastore(path='res/dd', compact=True)
            debug.write('Dump child container state to file...\n')

            # Clean again to make sure the first nosetest starts on a clean
            # slate
            self.datastore_admin.clear_datastore(prefix=self.sysname)
            # Set PYCC env var in case CEI needs to skip tests in pycc mode
            os.environ['PYCC_MODE'] = '1'
            # Enable CEI mode for the tests
            os.environ['CEI_LAUNCH_TEST'] = '1'

            debug.write('Start nose tests now...\n')
        except Exception as e:
            self.container_shutdown()
            raise e
예제 #5
0
    def begin(self):
        """Called before any tests are collected or run. Use this to
        perform any setup needed before testing begins.
        """
        # Make sure we initialize pyon before anything in this plugin executes
        from pyon.core import bootstrap
        if not bootstrap.pyon_initialized:
            bootstrap.bootstrap_pyon()

        try:
            from pyon.public import get_sys_name, CFG
            self.sysname = get_sys_name()

            # Clean exchanges and system queues out there
            try:
                connect_str = '-H %s -P 55672 -u %s -p %s -V %s' % (CFG.server.amqp.host,
                                                                    CFG.server.amqp.username,
                                                                    CFG.server.amqp.password,
                                                                    CFG.server.amqp.vhost)

                deleted_exchanges, deleted_queues = clean_by_sysname(connect_str, self.sysname)

                debug.write('Deleted exchanges:\n%s \n' % '\n'.join(deleted_exchanges))
                debug.write('Deleted queues:\n%s \n' % '\n'.join(deleted_queues))

            except Exception as e:
                pass

            # Force datastore loader to use the same sysname
            from pyon.datastore.datastore_admin import DatastoreAdmin
            self.datastore_admin = DatastoreAdmin(config=CFG)

            self.datastore_admin.clear_datastore(prefix=self.sysname)

            def die(signum, frame):
                # For whatever reason, the parent doesn't die some times
                # when getting KeyboardInterrupt.  Hence this signal
                # handler.

                # Signal is pass through. The child pycc gets
                # its own KeyboardInterrupt and will shut down accordingly.
                debug.write('Received Keyboard Interrupt. Exiting now.\n')
                os._exit(9)

            signal.signal(signal.SIGINT, die)

            def no_zombie(signum, frame):
                # Debug to figure out who's dying
                debug.write('SIGCHLD received\n')
                stack = []
                while frame:
                    stack.append(frame)
                    frame =frame.f_back
                stack.reverse()
                for frame in stack:
                    debug.write('Frame %s in %s at line %s\n' %
                            (frame.f_code.co_name,
                                frame.f_code.co_filename, frame.f_lineno))
                debug.write('Child is dead...Clean up now so there is no zombie\n')
                (pid, status) = os.wait()
                exitstatus, signum = status & 0xff, (status & 0xff00) >> 8
                debug.write('Child pid %d with exit status %d and signum %d\n' % (pid, exitstatus, signum))
            # Could be dangerous.  Comment this out.
            # signal.signal(signal.SIGCHLD, no_zombie)

            def container_started_cb(signum, frame):
                """Callback when child pycc service is ready"""
                self.container_started = True

            signal.signal(signal.SIGUSR1, container_started_cb)

            # Make sure the pycc process has the same sysname as the nose
            ccargs = ['bin/pycc', '-o', '--noshell', '-sp', '--sysname=%s' % self.sysname,
                    '--logcfg=res/config/logging.pycc.yml',
                    '--rel=%s' % self.rel,
                    "--config={'system': {'auto_bootstrap': True}}"]
            debug.write('Starting cc process: %s\n' % ' '.join(ccargs))
            newenv = os.environ.copy()
            po = subprocess.Popen(ccargs, env=newenv, close_fds=True)
            self.ccs.append(po)

            # Wait for container to be ready
            while not self.container_started:
                time.sleep(0.2)
            debug.write('Child container is ready...\n')

            # Dump datastore
            self.datastore_admin.dump_datastore(path='res/dd', compact=True)
            debug.write('Dump child container state to file...\n')

            # Clean again to make sure the first nosetest starts on a clean
            # slate
            self.datastore_admin.clear_datastore(prefix=self.sysname)
            # Enable CEI mode for the tests
            os.environ['CEI_LAUNCH_TEST'] = '1'

            debug.write('Start nose tests now...\n')
        except Exception as e:
            self.container_shutdown()
            raise e