def down(): mounts = [os.path.join(settings.ROOTFS, pkg[1]) for pkg in processPkgPath(settings.ROOT_PKG_DIR)] stdDir = _STD_DIR[:] stdDir.reverse() # Add the system relevant directories which have to be unmounted as well in # reversed order and unmount all directories for target in mounts + [os.path.join(settings.ROOTFS, path[1:]) for path in stdDir]: try: subprocess.check_output(['umount', target]) except subprocess.CalledProcessError as e: sys.stderr.write("Could not unmount '{0}'.\n\tExitcode: " '{1}'.format(target, e.returncode)) if e.output: sys.stderr.write('\tOutput: {0}'.format(e.output)) # Delete all the extra created mount points for mount in mounts: os.rmdir(mount)
def up(): mounts = [(pkg[0], os.path.join(settings.ROOTFS, pkg[1])) for pkg in processPkgPath(settings.ROOT_PKG_DIR)] # Create all the necessary mount points for mount in mounts: os.makedirs(mount[1]) # Add the system relevant directories which have to be mounted as well and # mount all directories for source, target in [(path, os.path.join(settings.ROOTFS, path[1:])) for path in _STD_DIR] + mounts: try: subprocess.check_output(['mount', '--bind', source, target]) except subprocess.CalledProcessError as e: sys.stderr.write("Could not mount '{0}'.\n\tExitcode: " '{1}'.format(source, e.returncode)) if e.output: sys.stderr.write('\tOutput: {0}'.format(e.output)) # Return the directory to the root of the container filesystem sys.stdout.write(settings.ROOTFS)
def main(reactor, cred, masterIP, masterPort, extIF, extPort, commPort, pkgPath, customConverters): log.startLogging(sys.stdout) def _err(reason): print(reason) reactor.stop() factory = PBClientFactory() reactor.connectTCP(masterIP, masterPort, factory) rosPath = [] for path in get_ros_paths() + [p for p, _ in processPkgPath(pkgPath)]: if path not in rosPath: rosPath.append(path) loader = Loader(rosPath) converter = Converter(loader) for customConverter in customConverters: # Get correct path/name of the converter module, className = customConverter.rsplit(".", 1) # Load the converter mod = __import__(module, fromlist=[className]) converter.addCustomConverter(getattr(mod, className)) client = RobotClient(reactor, commPort, extIF, extPort, loader, converter) d = factory.login(cred, client) d.addCallback(lambda ref: setattr(client, "_avatar", ref)) d.addErrback(_err) portal = Portal(client, (client,)) robot = CloudEngineWebSocketFactory(portal, "ws://localhost:{0}".format(extPort)) listenWS(robot) reactor.addSystemEventTrigger("before", "shutdown", client.terminate) reactor.run()
def __init__(self, reactor, masterIP, intIF, bridgeIF, envPort, rootfsDir, confDir, dataDir, srcDir, pkgDir): """ Initialize the Container Client. @param reactor: Reference to the twisted reactor. @type reactor: twisted::reactor @param masterIP: IP address of the Master process. @type masterIP: str @param intIF: Name of the network interface used for the internal network. @type intIF: str @param bridgeIF: Name of the bridge interface used for the container network. @type bridgeIF: str @param envPort: Port where the environment process running inside the container is listening for connections to other endpoints. (Used for port forwarding.) @type envPort: int @param rootfsDir: Filesystem path to the root directory of the container filesystem. @type rootfsDir: str @param confDir: Filesystem path to the directory where container configuration files should be stored. @type confDir: str @param dataDir: Filesystem path to the directory where temporary data of a container should be stored. @type dataDir: str @param srcDir: Filesystem path to the directory where the source of the cloud engine is located. @type srcDir: str @param pkgDir: Filesystem paths to the package directories as a list of tuples where each tuple contains the path to the directory in the host machine and the path to the directory to which the host directory will be bound in the container filesystem (without the @param rootfsDir). @type pkgDir: [(str, str)] """ self._reactor = reactor self._internalIP = getIP(intIF) self._envPort = envPort bridgeIP = getIP(bridgeIF) if masterIP in ('localhost', '127.0.0.1'): self._masterIP = bridgeIP else: self._masterIP = masterIP self._rootfs = rootfsDir self._confDir = confDir self._dataDir = dataDir self._srcDir = srcDir # Validate directory paths checkPath(self._confDir, 'Configuration') checkPath(self._dataDir, 'Data') checkPath(self._rootfs, 'Container file system') checkPath(self._srcDir, 'RCE source') # Validate executable paths checkExe(self._srcDir, 'environment.py') #checkExe(self._srcDir, 'launcher.py') # Process ROS package paths self._pkgDir = processPkgPath(pkgDir) for _, path in self._pkgDir: os.mkdir(os.path.join(self._rootfs, path)) self._nrs = set(range(100, 200)) self._containers = set() # Network configuration self._network = bridgeIP[:bridgeIP.rfind('.')] self._networkConf = _NETWORK_INTERFACES.format(network=self._network) # Common iptables references nat = iptc.Table(iptc.Table.NAT) self._prerouting = iptc.Chain(nat, 'PREROUTING') self._output = iptc.Chain(nat, 'OUTPUT')