示例#1
0
    def run_vadere(self):

        ret = 255
        logger.info("Run vadere in container")

        try:
            self.build_and_start_vadere_only()
            ret = 0  # all good if we reached this.

        except RuntimeError as cErr:
            logger.error(cErr)
            ret = 255
        except KeyboardInterrupt as K:
            logger.info("KeyboardInterrupt detected. Shutdown. ")
            ret = 128 + signal.SIGINT
            raise

        finally:
            # always stop container and delete if no error occurred
            err_state = ret
            logger.debug(f"cleanup with ret={ret}")

            # TODO: does not work

            # if self.vadere_runner is not None:
            #     self.vadere_runner.container_cleanup(has_error_state=err_state)
            # self.opp_runner.container_cleanup(has_error_state=err_state)

        return ret
示例#2
0
    def pull_images(self):

        try:
            self.client.images.get(self.image)
        except:
            logger.info(
                f"Docker image is missing. Try to pull {self.image} from repository."
            )
            self.client.images.pull(repository=self.rep, tag=self.tag)
示例#3
0
    def run_simulation_omnet_sumo(self):
        ret = 255  # fail
        self.build_opp_runner()

        try:
            sumo_args = self.ns["sumo_args"]
            if self.ns["create_sumo_container"]:
                self.build_sumo_runner()
                self.sumo_runner.single_launcher(
                    traci_port=sumo_args.get_value("--port"),
                    bind=sumo_args.get_value("--bind"),
                )

            if self.ns["override-host-config"]:
                self.ns["opp_args"].add_override(
                    f"--sumo-host={self.sumo_runner.name}:{sumo_args.get_value('--port')}"
                )

            # start OMNeT++ container and attach to it
            logger.info(f"start simulation {self.ns['run_name']} ...")
            opp_ret = self.opp_runner.exec_opp_run(
                arg_list=self.ns["opp_args"],
                result_dir=self.ns["result_dir"],
                experiment_label=self.ns["experiment_label"],
                run_args_override={},
            )
            ret = opp_ret["StatusCode"]
            if ret != 0:
                raise RuntimeError(
                    f"OMNeT++ container exited with StatusCode '{ret}'")

            if self.sumo_runner is not None:
                try:
                    self.sumo_runner.container.wait(timeout=600)
                except ReadTimeout:
                    logger.error(
                        f"Timeout (60s) reached while waiting for sumo container to finished"
                    )
                    ret = 255

        except RuntimeError as cErr:
            logger.error(cErr)
            ret = 255
        except KeyboardInterrupt as K:
            logger.info("KeyboardInterrupt detected. Shutdown. ")
            ret = 128 + signal.SIGINT
            raise
        finally:
            # always stop container and delete if no error occurred
            err_state = ret != 0
            logger.debug(f"cleanup with ret={ret}")
            if self.sumo_runner is not None:
                self.sumo_runner.container_cleanup(has_error_state=err_state)
            self.opp_runner.container_cleanup(has_error_state=err_state)
        return ret
示例#4
0
    def export_cmd(
        self,
        input_paths,
        output,
        scave_filter: Union[str, ScaveFilter] = None,
        recursive=True,
        options=None,
        print_selected_files=False,
    ):
        cmd = self._SCAVE_TOOL[:]
        cmd.append(self._EXPORT)
        cmd.append(self._OUTPUT)
        cmd.append(output)
        if scave_filter is not None:
            cmd.append(self._FILTER)
            if type(scave_filter) == str:
                cmd.append(self._config.escape(scave_filter))
            else:
                cmd.append(scave_filter.build(escape=True))

        if options is not None:
            cmd.extend(options)

        if len(input_paths) == 0:
            raise ValueError("no *.vec or *.sca files given.")

        # todo check if glob pattern exists first only then do this and the check
        opp_result_files = list()
        if any([_f for _f in input_paths if "*" in _f]):
            for file in input_paths:
                opp_result_files.extend(glob.glob(file, recursive=recursive))
        else:
            opp_result_files.extend(input_paths)

        opp_result_files = [
            f for f in opp_result_files
            if f.endswith(".vec") or f.endswith(".sca")
        ]
        if len(opp_result_files) == 0:
            raise ValueError("no opp input files selected.")

        log = "\n".join(opp_result_files)
        logger.info(f"found *.vec and *.sca:\n {log}")
        if print_selected_files:
            print("selected files:")
            for f in opp_result_files:
                print(f"\t{f}")

        cmd.extend(opp_result_files)
        return cmd
示例#5
0
    def run_simulation_omnet_vadere(self):
        ret = 255
        self.build_opp_runner()

        try:
            if self.ns["create_vadere_container"]:
                self.build_and_start_vadere_runner()

            if self.ns["override-host-config"]:
                self.ns["opp_args"].add(
                    f"--vadere-host={self.vadere_runner.name}")
            # start OMNeT++ container and attach to it.
            logger.info(f"start simulation {self.ns['run_name']} ...")
            opp_ret = self.opp_runner.exec_opp_run(
                arg_list=self.ns["opp_args"],
                result_dir=self.ns["result_dir"],
                experiment_label=self.ns["experiment_label"],
                run_args_override={},
            )

            ret = opp_ret["StatusCode"]
            if ret != 0:
                raise RuntimeError(
                    f"OMNeT++ container exited with StatusCode '{ret}'")

            if self.vadere_runner is not None:
                try:
                    self.vadere_runner.container.wait(
                        timeout=self.ns["v_wait_timeout"])
                except ReadTimeout:
                    logger.error(
                        f"Timeout ({self.ns['v_wait_timeout']}) reached while waiting for vadere container to finished"
                    )
                    ret = 255

        except RuntimeError as cErr:
            logger.error(cErr)
            ret = 255
        except KeyboardInterrupt as K:
            logger.info("KeyboardInterrupt detected. Shutdown. ")
            ret = 128 + signal.SIGINT
            raise
        finally:
            # always stop container and delete if no error occurred
            err_state = ret != 0
            logger.debug(f"cleanup with ret={ret}")
            if self.vadere_runner is not None:
                self.vadere_runner.container_cleanup(has_error_state=err_state)
            self.opp_runner.container_cleanup(has_error_state=err_state)
        return ret
示例#6
0
    def create_container(self, cmd="/init.sh", **run_args) -> Container:
        """
        run container. If no command is given execute the default entry point '/init.sh'
        """
        self.build_run_args(**run_args)  # set name if given
        command = self.wrap_command(cmd)
        logger.info(f"{'#'*10} create container [image:{self.image}]")
        logger.debug(f"cmd: \n{pprint.pformat(command, indent=2)}")
        logger.debug(f"runargs: \n{pprint.pformat(self.run_args, indent=2)}")

        c: Container = self.client.containers.create(
            image=self.image, command=command, **self.run_args
        )
        logger.info(f"{'#'*10} container created {c.name} [image:{self.image}]")
        return c
示例#7
0
 def run(self):
     logger.info("execute pre hooks")
     self.pre()
     logger.info("execute simulation")
     ret = self.dispatch_run()
     if ret != 0:
         raise RuntimeError("Error in Simulation")
     logger.info("execute post hooks")
     self.post()
     logger.info("done")
示例#8
0
    def exec(self, cmd):
        scave_cmd = subprocess.Popen(
            cmd,
            cwd=os.path.curdir,
            shell=False,
            stdin=None,
            env=os.environ.copy(),
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )

        try:
            scave_cmd.wait()
            if scave_cmd.returncode != 0:
                logger.error(f"return code was {scave_cmd.returncode}")
                logger.error("command:")
                logger.error(f"{pp.pprint(cmd)}")
                print(scave_cmd.stdout.read().decode("utf-8"))
                print(scave_cmd.stderr.read().decode("utf-8"))

            else:
                logger.info(f"return code was {scave_cmd.returncode}")
                print(scave_cmd.stdout.read().decode("utf-8"))

        except subprocess.TimeoutExpired:
            logger.info(f"scavetool timeout reached. Kill it")
            os.kill(scave_cmd.pid, signal.SIGKILL)
            time.sleep(0.5)
            if scave_cmd.returncode is None:
                logger.error("scavetool still not dead after SIGKILL")
                raise

        logger.info(f"return code: {scave_cmd.returncode}")
示例#9
0
    def run(self, cmd, perform_cleanup=True, **run_args):
        err = False

        self.pull_images()

        try:
            self._container = self.create_container(cmd, **run_args)
            logger.info(
                f"start container {self._container.name} with {{detach: {self.detach},"
                f" remove: {self.cleanupPolicy}, journal_tag: {self.journal_tag}}}"
            )
            self._container.start()
            if not self.detach:
                ret = self.wait()
            else:
                ret = {"Error": None, "StatusCode": 0}
        except (KeyboardInterrupt, SystemExit) as kInter:
            logger.warning(
                f"KeyboardInterrupt. Stop Container {self._container.name} ..."
            )
            err = True  # stop but do not delete container
            raise  # re-raise so other parts can react to SIGINT
        except ReadTimeout as e:
            logger.error("wait timeout reached")
            err = True  # stop but do not delete container
            raise RuntimeError(e)
        except docker.errors.APIError as e:
            logger.error(f"some API error occurred")
            logger.error(e.explanation)
            err = True  # stop but do not delete container
            raise RuntimeError(e)
        except BaseException as e:
            logger.error(f"some error occurred")
            err = True  # stop but do not delete container
            raise RuntimeError(e)
        finally:
            if not self.detach and perform_cleanup:
                self.container_cleanup(has_error_state=err)
        return ret
示例#10
0
    def run_simulation_vadere_ctl(self):

        ret = 255
        logger.info(
            "Control vadere without omnetpp. Client: controller, server: vadere, port: 9999"
        )

        output_dir = os.path.join(
            os.getcwd(),
            f"results/vadere_controlled_{self.ns['experiment_label']}/vadere.d",
        )
        os.makedirs(output_dir, exist_ok=True)

        self.build_control_runner()

        try:
            if self.ns["create_vadere_container"]:
                self.build_and_start_vadere_runner(port=9999,
                                                   output_dir=output_dir)
                logger.info(f"start simulation {self.ns['run_name']} ...")

            ctl_ret = self.exec_control_runner(mode="client")
            ret = ctl_ret["StatusCode"]
            if ret != 0:
                raise RuntimeError(
                    f"Control container exited with StatusCode '{ret}'")

            if self.vadere_runner is not None:
                try:
                    self.vadere_runner.container.wait(
                        timeout=self.ns["v_wait_timeout"])
                except ReadTimeout:
                    logger.error(
                        f"Timeout ({self.ns['v_wait_timeout']}) reached while waiting for vadere container to finished"
                    )
                    ret = 255
        except RuntimeError as cErr:
            logger.error(cErr)
            ret = 255
        except KeyboardInterrupt as K:
            logger.info("KeyboardInterrupt detected. Shutdown. ")
            ret = 128 + signal.SIGINT
            raise
        finally:
            # always stop container and delete if no error occurred
            err_state = ret != 0
            logger.debug(f"cleanup with ret={ret}")
            if self.vadere_runner is not None:
                self.vadere_runner.container_cleanup(has_error_state=err_state)
            if self.control_runner is not None:
                self.control_runner.container_cleanup(
                    has_error_state=err_state)
        return ret
示例#11
0
    def apply_reuse_policy(self):
        try:
            if self.name == "":
                return
            _container = self.client.containers.get(self.name)
            reuse_policy = self.reuse_policy

            if reuse_policy == DockerReuse.REMOVE_RUNNING:
                _container.stop()
                _container.remove()
                logger.info(
                    f"stop and remove existing container with name '{self.name}'"
                )
            elif reuse_policy == DockerReuse.REMOVE_STOPPED:
                if _container.status == "running":
                    raise ValueError(
                        f"container is still running but reuse policy is {reuse_policy}."
                    )
                _container.remove()
                logger.info(f"remove existing container with name '{self.name}'")
            elif (
                reuse_policy == DockerReuse.REUSE_STOPPED
                or reuse_policy == DockerReuse.REUSE_RUNNING
            ):
                if _container.status == "running":
                    _container.stop()
                    logger.info(f"stop existing container with name '{self.name}'")
            elif reuse_policy == DockerReuse.NEW_ONLY:
                # container exists. --> error here
                raise ValueError(
                    f"container exists with status: {_container.status}. Reuse policy {reuse_policy} "
                    f"requires that container does not exist."
                )
            else:
                raise ValueError(f"unknown reuse policy provided {reuse_policy}")

        except NotFound as notFoundErr:
            pass  # ignore do nothing
示例#12
0
 def write(self, container_name, output: bytes, *args, **kwargs):
     logger.info(f"write output of {container_name}  to {self.path}")
     os.makedirs(os.path.split(self.path)[0], exist_ok=True)
     with open(self.path, "w", encoding="utf-8") as log:
         log.write(output.decode("utf-8"))
示例#13
0
 def count_map(self):
     # lazy load data if needed
     if self._count_map is None:
         logger.info("load count map from HDF")
         self._count_map = self._count_p[self._count_slice, :]
     return self._count_map
示例#14
0
 def map(self):
     if self._map is None:
         logger.info("load map")
         self._map = self._map_p[self._map_slice, :]
     return self._map