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()
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 )
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)