Example #1
0
    def manage_nextboot_symlink(self, action):
        """
        Messes with the symlink in /tftpboot/pxelinux.cfg/
        Depending on 'action'
        * 'cleanup' or 'harddrive' : clear the symlink
          corresponding to this CMC
        * 'frisbee' : define a symlink so that next boot
          will run the frisbee image
        see rhubarbe.conf for configurable options
        """

        the_config = Config()
        root = the_config.value('pxelinux', 'config_dir')
        frisbee = the_config.value('pxelinux', 'frisbee_image')

        # of the form 01-00-03-1d-0e-03-53
        mylink = "01-" + self.control_mac_address().replace(':', '-')
        source = os.path.join(root, mylink)

        if action in ('cleanup', 'harddrive'):
            if os.path.exists(source):
                logger.info(f"Removing {source}")
                os.remove(source)
        elif action in ('frisbee', ):
            if os.path.exists(source):
                os.remove(source)
            logger.info(f"Creating {source}")
            os.symlink(frisbee, source)
        else:
            logger.critical(
                f"manage_nextboot_symlink : unknown action {action}")
Example #2
0
    def manage_nextboot_symlink(self, action):
        """
        Messes with the symlink in /tftpboot/pxelinux.cfg/
        Depending on 'action'
        * 'cleanup' or 'harddrive' : clear the symlink corresponding to this CMC
        * 'frisbee' : define a symlink so that next boot will run the frisbee image
        see rhubarbe.conf for configurable options
        """

        the_config = Config()
        root = the_config.value("pxelinux", "config_dir")
        frisbee = the_config.value("pxelinux", "frisbee_image")

        # of the form 01-00-03-1d-0e-03-53
        mylink = "01-" + self.control_mac_address().replace(":", "-")
        source = os.path.join(root, mylink)
        dest = os.path.join(root, frisbee)

        if action in ("cleanup", "harddrive"):
            if os.path.exists(source):
                logger.info("Removing {}".format(source))
                os.remove(source)
        elif action in ("frisbee"):
            if os.path.exists(source):
                os.remove(source)
            logger.info("Creating {}".format(source))
            os.symlink(frisbee, source)
        else:
            logger.critical("manage_nextboot_symlink : unknown action {}".format(action))
Example #3
0
    async def start(self):  # pylint: disable=r0914
        """
        Start a collector instance; returns a port_number
        """
        the_config = Config()
        netcat = the_config.value('frisbee', 'netcat')
        local_ip = the_config.local_control_ip()

        # should use default.ndz if not provided
        # use shell-style as we rather have bash handle the redirection
        # we instruct bash to exec nc;
        # otherwise when cleaning up we just kill the bash process
        # but nc is left lingering behind
        # WARNING: it is intended that format contains {port}
        # for future formatting
        command_format_ubuntu = (
            f"exec {netcat} -d -l {local_ip} {{port}} > {self.image}"
            f" 2> /dev/null")
        command_format_fedora = (
            f"exec {netcat}    -l {local_ip} {{port}} > {self.image}"
            f" 2> /dev/null")

        netcat_style = the_config.value('frisbee', 'netcat_style')
        if netcat_style not in ('fedora', 'ubuntu'):
            message = f"wrong netcat_style {netcat_style}"
            print(message)
            raise Exception(message)
        command_format = (command_format_fedora if netcat_style == 'fedora'
                          else command_format_ubuntu)

        nb_attempts = int(the_config.value('networking', 'pattern_size'))
        pat_port = the_config.value('networking', 'pattern_port')
        for i in range(1, nb_attempts + 1):
            pat = str(i)
            port = str(
                eval(  # pylint: disable=w0123
                    pat_port.replace('*', pat)))
            command = command_format.format(port=port)
            self.subprocess = await asyncio.create_subprocess_shell(command)
            await asyncio.sleep(1)
            # after such a short time, frisbeed should not have returned yet
            # if is has, we try our luck on another couple (ip, port)
            command_line = command
            if self.subprocess.returncode is None:
                logger.info(f"collector started: {command_line}")
                await self.feedback('info',
                                    f"collector started on {self.image}")
                self.port = port
                return port
            else:
                logger.warning(
                    f"failed to start collector with {command_line}")
        logger.critical("Could not find a free port to start collector")
        raise Exception("Could not start collector server")
Example #4
0
    async def start(self):  # pylint: disable=r0914
        """
        Start a frisbeed instance
        returns a tuple multicast_group, port_number
        """
        the_config = Config()
        server = the_config.value('frisbee', 'server')
        server_options = the_config.value('frisbee', 'server_options')
        local_ip = the_config.local_control_ip()
        # in Mibps
        bandwidth = self.bandwidth * 2**20
        # should use default.ndz if not provided
        command_common = [
            server, "-i", local_ip, "-W",
            str(bandwidth), self.image
        ]
        # add configured extra options
        command_common += server_options.split()

        nb_attempts = int(the_config.value('networking', 'pattern_size'))
        pat_ip = the_config.value('networking', 'pattern_multicast')
        pat_port = the_config.value('networking', 'pattern_port')
        for i in range(1, nb_attempts + 1):
            pat = str(i)
            multicast_group = pat_ip.replace('*', pat)
            multicast_port = str(
                eval(  # pylint: disable=w0123
                    pat_port.replace('*', pat)))
            command = command_common + [
                "-m",
                multicast_group,
                "-p",
                multicast_port,
            ]
            self.subprocess = await asyncio.create_subprocess_exec(
                *command,
                stdout=asyncio.subprocess.PIPE,
                stderr=asyncio.subprocess.STDOUT)
            await asyncio.sleep(1)
            # after such a short time, frisbeed should not have returned yet
            # if it has, we try our luck on another couple (ip, port)
            command_line = " ".join(command)
            if self.subprocess.returncode is None:
                self.multicast_group = multicast_group
                self.multicast_port = multicast_port
                await self.feedback('info', f"started {self}")
                return multicast_group, multicast_port
            else:
                logger.warning(
                    f"failed to start frisbeed with `{command_line}`"
                    f" -> {self.subprocess.returncode}")
        logger.critical(f"could not start frisbee server !!! on {self.image}")
        raise Exception(f"could not start frisbee server !!! on {self.image}")
Example #5
0
    def check_binaries(self):
        # imagezip and frisbee are required on the pxe image only
        names = ('server', 'netcat')
        binaries = [self.value('frisbee', name) for name in names]

        for binary in binaries:
            checked = self.check_file_in_path(binary)
            if not checked:
                message = f"Binary {binary} not found in PATH"
                logger.critical(message)
                raise Exception(message)
            else:
                print(f"Found binary {binary} as {checked}")
Example #6
0
    async def start(self):
        """
        Start a frisbeed instance
        returns a tuple multicast_group, port_number
        """
        the_config = Config()
        server = the_config.value('frisbee', 'server')
        server_options = the_config.value('frisbee', 'server_options')
        local_ip = the_config.local_control_ip()
        # in Mibps
        bandwidth = self.bandwidth * 2**20
        # should use default.ndz if not provided
        command_common = [
            server, "-i", local_ip, "-W", str(bandwidth), self.image
            ]
        # add configured extra options
        command_common += server_options.split()

        nb_attempts = int(the_config.value('networking', 'pattern_size'))
        pat_ip   = the_config.value('networking', 'pattern_multicast')
        pat_port = the_config.value('networking', 'pattern_port')
        for i in range(1, nb_attempts+1):
            pat = str(i)
            multicast_group = pat_ip.replace('*', pat)
            multicast_port = str(eval(pat_port.replace('*', pat)))
            command = command_common + [
                "-m", multicast_group, "-p", multicast_port,
                ]
            self.subprocess = await asyncio.create_subprocess_exec(
                *command,
                stdout = asyncio.subprocess.PIPE,
                stderr = asyncio.subprocess.STDOUT
                )
            await asyncio.sleep(1)
            # after such a short time, frisbeed should not have returned yet
            # if is has, we try our luck on another couple (ip, port)
            command_line = " ".join(command)
            if self.subprocess.returncode is None:
                self.multicast_group = multicast_group
                self.multicast_port = multicast_port
                await self.feedback('info', "started {}".format(self))
                return multicast_group, multicast_port
            else:
                logger.warning("failed to start frisbeed with {}".format(command_line))
        logger.critical("Could not find a free IP multicast address + port to start frisbeed")
        raise Exception("Could not start frisbee server")
Example #7
0
    async def start(self):
        """
        Start a collector instance; returns a port_number
        """
        the_config = Config()
        netcat = the_config.value('frisbee', 'netcat')
        local_ip = the_config.local_control_ip()
        # should use default.ndz if not provided
        # use shell-style as we rather have bash handle the redirection
        # we instruct bash to exec nc; otherwise when cleaning up we just kill the bash process
        # but nc is left lingering behind
        # WARNING: it is intended that format contains {port} for future formatting
        command_format = "exec {} -d -l {} {{port}} > {} 2> /dev/null"\
                        .format(netcat, local_ip, self.image)

        nb_attempts = int(the_config.value('networking', 'pattern_size'))
        pat_port = the_config.value('networking', 'pattern_port')
        for i in range(1, nb_attempts+1):
            pat = str(i)
            port = str(eval(pat_port.replace('*', pat)))
            command = command_format.format(port=port)
            self.subprocess = \
              await asyncio.create_subprocess_shell(command)
            await asyncio.sleep(1)
            # after such a short time, frisbeed should not have returned yet
            # if is has, we try our luck on another couple (ip, port)
            command_line = command
            if self.subprocess.returncode is None:
                logger.info("collector started: {}".format(command_line))
                await self.feedback('info', "collector started on {}".format(self.image))
                self.port = port
                return port
            else:
                logger.warning("failed to start collector with {}".format(command_line))
        logger.critical("Could not find a free port to start collector")
        raise Exception("Could not start collector server")