Beispiel #1
0
    def _register(self, manifest, refresh_interval=None):
        app_presence = presence.EndpointPresence(context.GLOBAL.zk.conn,
                                                 manifest)

        try:
            app_presence.register()

            if manifest.get('tickets', None):
                _get_tickets(manifest['name'], manifest, self.container_dir)

            _start_service_sup(self.container_dir)
        except exc.ContainerSetupError as err:
            app_abort.abort(self.tm_env, manifest['name'], reason=str(err))

        # If tickets are not ok, app will be aborted. Waiting for tickets
        # in the loop is harmless way to wait for that.
        #
        # If tickets acquired successfully, services will start, and
        # tickets will be refreshed after each interval.
        tkts_spool_dir = os.path.join(self.container_dir, 'root', 'var',
                                      'spool', 'tickets')

        while True:
            time.sleep(refresh_interval)
            reply = tickets.request_tickets(context.GLOBAL.zk.conn,
                                            manifest['name'])
            if reply:
                tickets.store_tickets(reply, tkts_spool_dir)
            else:
                _LOGGER.error('Error requesting tickets.')
Beispiel #2
0
    def register_cmd(approot, refresh_interval, manifest, container_dir):
        """Register container presence."""
        try:
            _LOGGER.info('Configuring sigterm handler.')
            signal.signal(utils.term_signal(), sigterm_handler)

            tm_env = appenv.AppEnvironment(approot)
            app = app_manifest.read(manifest)

            app_presence = presence.EndpointPresence(context.GLOBAL.zk.conn,
                                                     app)

            # If tickets are not ok, app will be aborted.
            #
            # If tickets acquired successfully, services will start, and
            # tickets will be refreshed after each interval.
            refresh = False
            try:
                app_presence.register()
                refresh = _get_tickets(app, container_dir)
                _start_service_sup(tm_env, app, container_dir)
            except exc.ContainerSetupError as err:
                app_abort.abort(container_dir,
                                why=err.reason,
                                payload=traceback.format_exc())

            while True:
                # Need to sleep anyway even if not refreshing tickets.
                time.sleep(refresh_interval)
                if refresh:
                    _refresh_tickets(app, container_dir)
        finally:
            _LOGGER.info('Stopping zookeeper.')
            context.GLOBAL.zk.conn.stop()
Beispiel #3
0
    def _run(self, manifest):
        context.GLOBAL.zk.conn.add_listener(zkutils.exit_on_lost)

        with lc.LogContext(_LOGGER, self._service.name,
                           lc.ContainerAdapter) as log:
            log.info('Running %r', self._service.directory)

            _sockets = runtime.allocate_network_ports(
                '0.0.0.0', manifest
            )

            app = runtime.save_app(manifest, self._service.data_dir)

            app_presence = presence.EndpointPresence(
                context.GLOBAL.zk.conn,
                manifest
            )

            app_presence.register_identity()
            app_presence.register_running()

            try:
                client = self._get_client()

                try:
                    container = _create_container(
                        self._tm_env,
                        self._get_config(),
                        client,
                        app
                    )
                except docker.errors.ImageNotFound:
                    raise exc.ContainerSetupError(
                        'Image {0} was not found'.format(app.image),
                        app_abort.AbortedReason.IMAGE
                    )

                container.start()
                container.reload()

                _LOGGER.info('Container is running.')
                app_presence.register_endpoints()
                appevents.post(
                    self._tm_env.app_events_dir,
                    events.ServiceRunningTraceEvent(
                        instanceid=app.name,
                        uniqueid=app.uniqueid,
                        service='docker'
                    )
                )

                while container.status == 'running':
                    container.wait(timeout=10)
                    container.reload()
            finally:
                _LOGGER.info('Stopping zookeeper.')
                context.GLOBAL.zk.conn.stop()
Beispiel #4
0
    def _run(self, manifest):
        context.GLOBAL.zk.conn.add_listener(zkutils.exit_on_lost)

        with lc.LogContext(_LOGGER, self._service.name,
                           lc.ContainerAdapter) as log:
            log.info('Running %r', self._service.directory)

            manifest['ephemeral_ports']['tcp'] = []
            manifest['ephemeral_ports']['udp'] = []

            _create_docker_log_symlink(self._service.data_dir)

            app = runtime.save_app(manifest, self._service.data_dir)

            volume_mapping = self._get_volume_mapping()

            app_presence = presence.EndpointPresence(context.GLOBAL.zk.conn,
                                                     manifest)

            app_presence.register_identity()
            app_presence.register_running()

            client = self._get_client()

            try:
                container = _create_container(self._tm_env, self._get_config(),
                                              client, app, volume_mapping)
            except docker.errors.ImageNotFound:
                raise exc.ContainerSetupError(
                    'Image {0} was not found'.format(app.image),
                    app_abort.AbortedReason.IMAGE)

            container.start()
            container.reload()

            _update_network_info_in_manifest(container, manifest)
            # needs to share manifest with container
            if volume_mapping:
                container_data_dir = next(iter(volume_mapping))
                runtime.save_app(manifest,
                                 container_data_dir,
                                 app_json='app.json')

            _LOGGER.info('Container is running.')
            app_presence.register_endpoints()
            trace.post(
                self._tm_env.app_events_dir,
                events.ServiceRunningTraceEvent(instanceid=app.name,
                                                uniqueid=app.uniqueid,
                                                service='docker'))

            _print_container_logs(container)
Beispiel #5
0
    def register(approot, refresh_interval, manifest, container_dir,
                 appevents_dir):
        """Register container presence."""
        del appevents_dir
        tm_env = appmgr.AppEnvironment(approot)

        app = yaml.load(manifest.read())
        appname = app['name']

        app_presence = presence.EndpointPresence(
            context.GLOBAL.zk.conn,
            app
        )

        try:
            app_presence.register()
            _get_tickets(appname, app, container_dir)
            _start_service_sup(container_dir)
        except exc.ContainerSetupError as err:
            app_abort.abort(
                tm_env,
                appname,
                reason=str(err)
            )

        # If tickets are not ok, app will be aborted. Waiting for tickets
        # in the loop is harmless way to wait for that.
        #
        # If tickets acquired successfully, services will start, and
        # tickets will be refreshed after each interval.
        tkts_spool_dir = os.path.join(
            container_dir, 'root', 'var', 'spool', 'tickets')

        while True:
            time.sleep(refresh_interval)
            reply = tickets.request_tickets(context.GLOBAL.zk.conn,
                                            appname)
            if reply:
                tickets.store_tickets(reply, tkts_spool_dir)
            else:
                _LOGGER.error('Error requesting tickets.')
    def test_registration(self):
        """Verifies presence registration."""
        treadmill.sysinfo.hostname.return_value = 'myhostname'
        manifest = {
            'task':
            't-0001',
            'name':
            'foo.test1',
            'uniqueid':
            'AAAAAA',
            'proid':
            'andreik',
            'services': [{
                'command': '/usr/bin/python -m SimpleHTTPServer',
                'name': 'web_server',
                'restart': {
                    'interval': 60,
                    'limit': 3
                }
            }, {
                'command': '/usr/bin/python -m SimpleHTTPServer',
                'name': 'another_server'
            }, {
                'command': 'sshd -D -f /etc/ssh/sshd_config',
                'name': 'sshd',
                'proid': None
            }],
            'endpoints': [{
                'port': 22,
                'name': 'ssh',
                'real_port': 5001,
            }, {
                'port': 8000,
                'name': 'http',
                'real_port': 5000,
            }]
        }
        app_presence = presence.EndpointPresence(self.zkclient, manifest)
        app_presence.register_endpoints()
        kazoo.client.KazooClient.create.assert_has_calls([
            mock.call('/endpoints/foo/test1:tcp:ssh',
                      value=b'myhostname:5001',
                      acl=mock.ANY,
                      ephemeral=True,
                      makepath=True,
                      sequence=False),
            mock.call('/endpoints/foo/test1:tcp:http',
                      value=b'myhostname:5000',
                      acl=mock.ANY,
                      ephemeral=True,
                      makepath=True,
                      sequence=False),
        ])

        retry_happened = []

        def node_exists(*_args, **_kwargs):
            """Simulate existence of ephemeral node."""
            if retry_happened:
                return
            else:
                retry_happened.append(1)
                raise kazoo.client.NodeExistsError()

        kazoo.client.KazooClient.create.reset()
        kazoo.client.KazooClient.create.side_effect = node_exists
        kazoo.client.KazooClient.get.return_value = ('{}', {})
        app_presence.register_endpoints()
        self.assertTrue(retry_happened)
        self.assertTrue(time.sleep.called)
        kazoo.client.KazooClient.create.assert_has_calls([
            mock.call('/endpoints/foo/test1:tcp:ssh',
                      value=b'myhostname:5001',
                      acl=mock.ANY,
                      ephemeral=True,
                      makepath=True,
                      sequence=False),
            mock.call('/endpoints/foo/test1:tcp:http',
                      value=b'myhostname:5000',
                      acl=mock.ANY,
                      ephemeral=True,
                      makepath=True,
                      sequence=False),
        ])

        kazoo.client.KazooClient.create.reset()
        kazoo.client.KazooClient.create.side_effect = (
            kazoo.client.NodeExistsError)
        self.assertRaises(exc.ContainerSetupError,
                          app_presence.register_endpoints)
Beispiel #7
0
    def test_registration(self):
        """Verifies presence registration."""
        treadmill.sysinfo.hostname.return_value = 'myhostname'
        manifest = yaml.load("""
---
name: foo.test1
proid: andreik
services:
- command: /usr/bin/python -m SimpleHTTPServer
  name: web_server
  restart_count: 3
- command: /usr/bin/python -m SimpleHTTPServer
  name: another_server
- command: sshd -D -f /etc/ssh/sshd_config
  endpoints:
  name: sshd
  proid: ~
endpoints:
- {name: ssh,  port: 22,   real_port: 5001}
- {name: http, port: 8000, real_port: 5000}
vip: {ip0: 192.168.0.1, ip1: 192.168.0.2}
task: t-0001
""")
        app_presence = presence.EndpointPresence(self.zkclient, manifest)
        app_presence.register_endpoints()
        kazoo.client.KazooClient.create.assert_has_calls([
            mock.call('/endpoints/foo/test1:ssh',
                      'myhostname:5001',
                      ephemeral=True,
                      makepath=True,
                      acl=mock.ANY,
                      sequence=False),
            mock.call('/endpoints/foo/test1:http',
                      'myhostname:5000',
                      ephemeral=True,
                      makepath=True,
                      acl=mock.ANY,
                      sequence=False),
        ])

        retry_happened = []

        def node_exists(*_args, **_kwargs):
            """Simulate existence of ephemeral node."""
            if retry_happened:
                return
            else:
                retry_happened.append(1)
                raise kazoo.client.NodeExistsError()

        kazoo.client.KazooClient.create.reset()
        kazoo.client.KazooClient.create.side_effect = node_exists
        app_presence.register_endpoints()
        self.assertTrue(retry_happened)
        self.assertTrue(time.sleep.called)
        kazoo.client.KazooClient.create.assert_has_calls([
            mock.call('/endpoints/foo/test1:ssh',
                      'myhostname:5001',
                      ephemeral=True,
                      makepath=True,
                      acl=mock.ANY,
                      sequence=False),
            mock.call('/endpoints/foo/test1:http',
                      'myhostname:5000',
                      ephemeral=True,
                      makepath=True,
                      acl=mock.ANY,
                      sequence=False),
        ])
Beispiel #8
0
    def _run(self, manifest):
        context.GLOBAL.zk.conn.add_listener(zkutils.exit_on_lost)

        with lc.LogContext(_LOGGER, self._service.name,
                           lc.ContainerAdapter) as log:
            log.info('Running %r', self._service.directory)

            manifest['ephemeral_ports']['tcp'] = []
            manifest['ephemeral_ports']['udp'] = []

            # create container_data dir
            container_data_dir = os.path.join(self._service.data_dir,
                                              'container_data')

            log.info('container_data %r', container_data_dir)

            fs.mkdir_safe(container_data_dir)

            # volume mapping config : read-only mapping
            volume_mapping = {
                container_data_dir: {
                    'bind': 'c:\\container_data',
                    'mode': 'ro'
                }
            }

            app = runtime.save_app(manifest, self._service.data_dir)

            app_presence = presence.EndpointPresence(context.GLOBAL.zk.conn,
                                                     manifest)

            app_presence.register_identity()
            app_presence.register_running()

            client = self._get_client()

            try:
                container = _create_container(self._tm_env, self._get_config(),
                                              client, app, volume_mapping)
            except docker.errors.ImageNotFound:
                raise exc.ContainerSetupError(
                    'Image {0} was not found'.format(app.image),
                    app_abort.AbortedReason.IMAGE)

            container.start()
            container.reload()

            _update_network_info_in_manifest(container, manifest)
            runtime.save_app(manifest, container_data_dir, app_json='app.json')

            _LOGGER.info('Container is running.')
            app_presence.register_endpoints()
            trace.post(
                self._tm_env.app_events_dir,
                events.ServiceRunningTraceEvent(instanceid=app.name,
                                                uniqueid=app.uniqueid,
                                                service='docker'))

            while container.status == 'running':
                container.wait(timeout=10)
                container.reload()