예제 #1
0
파일: runtime.py 프로젝트: linbai/treadmill
    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)
예제 #2
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()
예제 #3
0
def run(tm_env, container_dir, manifest):
    """Creates container environment and prepares to exec root supervisor.
    """
    _LOGGER.info('Running %r', container_dir)

    unique_name = appcfg.manifest_unique_name(manifest)

    # Generate resources requests
    fs.mkdir_safe(os.path.join(container_dir, 'resources'))

    cgroup_client = tm_env.svc_cgroup.make_client(
        os.path.join(container_dir, 'resources', 'cgroups')
    )
    localdisk_client = tm_env.svc_localdisk.make_client(
        os.path.join(container_dir, 'resources', 'localdisk')
    )
    network_client = tm_env.svc_network.make_client(
        os.path.join(container_dir, 'resources', 'network')
    )

    # Cgroup
    cgroup_req = {
        'memory': manifest['memory'],
        'cpu': manifest['cpu'],
    }
    # Local Disk
    localdisk_req = {
        'size': manifest['disk'],
    }
    # Network
    network_req = {
        'environment': manifest['environment'],
    }

    cgroup_client.put(unique_name, cgroup_req)
    localdisk_client.put(unique_name, localdisk_req)
    if not manifest['shared_network']:
        network_client.put(unique_name, network_req)

    # Apply memory limits first thing, so that app_run does not consume memory
    # from treadmill/core.
    app_cgroups = cgroup_client.wait(unique_name)
    _apply_cgroup_limits(app_cgroups)
    localdisk = localdisk_client.wait(unique_name)
    app_network = network_client.wait(unique_name)

    img_impl = image.get_image(tm_env, manifest)

    manifest['network'] = app_network
    # FIXME: backward compatibility for TM 2.0. Remove in 3.0
    manifest['vip'] = {
        'ip0': app_network['gateway'],
        'ip1': app_network['vip'],
    }

    # Allocate dynamic ports
    #
    # Ports are taken from ephemeral range, by binding to socket to port 0.
    #
    # Sockets are then put into global list, so that they are not closed
    # at gc time, and address remains in use for the lifetime of the
    # supervisor.
    sockets = runtime.allocate_network_ports(
        app_network['external_ip'], manifest
    )

    app = runtime.save_app(manifest, container_dir)

    if not app.shared_network:
        _unshare_network(tm_env, container_dir, app)

    # Create and format the container root volume.
    root_dir = _create_root_dir(container_dir, localdisk)

    # NOTE: below here, MOUNT namespace is private

    # Unpack the image to the root directory.
    img_impl.unpack(container_dir, root_dir, app)

    # If network is shared, close sockets before starting the
    # supervisor, as these ports will be use be container apps.
    if app.shared_network:
        for socket_ in sockets:
            socket_.close()

    # hook container
    apphook.configure(tm_env, app, container_dir)
    subproc.exec_pid1(
        [
            's6_svscan',
            '-s',
            os.path.join(container_dir, 'sys')
        ],
        propagation='slave',
        # We need to keep our mapped ports open
        close_fds=False
    )
예제 #4
0
def run(tm_env, container_dir, manifest, watchdog, terminated):
    """Creates container environment and prepares to exec root supervisor.
    """
    _LOGGER.info('Running %r', container_dir)

    # Apply memory limits first thing, so that app_run does not consume memory
    # from treadmill/core.
    _apply_cgroup_limits(tm_env, container_dir, manifest)

    img_impl = image.get_image(tm_env, manifest)

    unique_name = appcfg.manifest_unique_name(manifest)
    # First wait for the network device to be ready
    network_client = tm_env.svc_network.make_client(
        os.path.join(container_dir, 'network'))
    app_network = network_client.wait(unique_name)

    manifest['network'] = app_network
    # FIXME: backward compatibility for TM 2.0. Remove in 3.0
    manifest['vip'] = {
        'ip0': app_network['gateway'],
        'ip1': app_network['vip'],
    }

    # Allocate dynamic ports
    #
    # Ports are taken from ephemeral range, by binding to socket to port 0.
    #
    # Sockets are then put into global list, so that they are not closed
    # at gc time, and address remains in use for the lifetime of the
    # supervisor.
    sockets = runtime.allocate_network_ports(app_network['external_ip'],
                                             manifest)

    app = runtime.save_app(manifest, container_dir)

    if not app.shared_network:
        _unshare_network(tm_env, app)

    # Create root directory structure (chroot base).
    # container_dir/<subdir>
    root_dir = os.path.join(container_dir, 'root')

    # Create and format the container root volume.
    _create_root_dir(tm_env, container_dir, root_dir, app)

    # NOTE: below here, MOUNT namespace is private

    # Unpack the image to the root directory.
    img_impl.unpack(container_dir, root_dir, app)

    # If network is shared, close sockets before starting the
    # supervisor, as these ports will be use be container apps.
    if app.shared_network:
        for socket_ in sockets:
            socket_.close()

    watchdog.remove()

    if not terminated:
        # hook container
        apphook.configure(tm_env, app)

        sys_dir = os.path.join(container_dir, 'sys')
        supervisor.exec_root_supervisor(sys_dir)
예제 #5
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()