Ejemplo n.º 1
0
 def test_type_success(self):
     test = "hello world"
     ensure_type(
         "test",
         test,
         str,
     )
Ejemplo n.º 2
0
    def from_json(cls, string):
        """
        Takes a JSON encoded string and build a `Script`.

        Parameters
        ----------
            string: str
                JSON encoded string.

        Returns
        -------
        Script:
            Which was paresed from the JSON encoded string.

        Raises
        ------
            TypeError:
                If programs and filesystems have the wrong type.
        """
        data = json.loads(string)

        ensure_type("programs", data["programs"], list)
        ensure_type("filesystems", data["filesystems"], list)

        ensure_type_array("programs", data["programs"], dict)
        ensure_type_array("filesystems", data["filesystems"], dict)

        return cls(
            data["name"],
            [ScriptEntryProgram(**program) for program in data["programs"]],
            [ScriptEntryFilesystem(**file) for file in data["filesystems"]],
        )
Ejemplo n.º 3
0
def prog_log_disable(program):
    """
    This function disables the log transfer for a `ProgramModel` by sending a
    command to the slave. If the slave is offline an error will be returned.

    Parameters
    ----------
        program: ProgramModel
            A valid `ProgramModel`.

    Raises
    ------
        SlaveOfflineError
        TypeError:
            If `program` is not an `ProgramModel`
    """
    ensure_type("program", program, ProgramModel)

    LOGGER.info(
        "Disabling logging for program %s on slave %s",
        program.name,
        program.slave.name,
    )

    if not program.slave.is_online:
        raise SlaveOfflineError('', '', 'log_disable', program.slave.name)

    notify_slave(
        Command(
            method="disable_logging",
            target_uuid=program.programstatus.command_uuid,
        ),
        program.slave.id,
    )
Ejemplo n.º 4
0
 def test_type_multi(self):
     test = "hello world"
     ensure_type(
         "test",
         test,
         int,
         str,
     )
Ejemplo n.º 5
0
def notify_slave(command, slave_id):
    """
    Sending the given `message` to the notification channel. Indicating that
    the message is an error message.

    Parameters
    ----------
        message: JSON object
            This message is send to the web interface with an Status.err()
            wrapped around.
    """
    ensure_type("command", command, Command)
    Group('client_' + str(slave_id)).send({'text': command.to_json()})
Ejemplo n.º 6
0
def filesystem_type_check(
        source_path,
        source_type,
        destination_path,
        destination_type,
        backup_ending,
):
    """
    Check the types of the shared input of filesystem_move and filesystem_restore.
    """
    uty.ensure_type("source_path", source_path, str)
    uty.ensure_type("destination_path", destination_path, str)
    uty.ensure_type("backup_ending", backup_ending, str)
    uty.ensure_type("PATH_TYPE_SET", PATH_TYPE_SET, list)

    if not source_type in PATH_TYPE_SET:
        raise ValueError(
            "The source_type has to be one of {}".format(PATH_TYPE_SET))
    if not destination_type in PATH_TYPE_SET:
        raise ValueError(
            "The destination_type has to be one of {}".format(PATH_TYPE_SET))

    source_path = up.remove_trailing_path_seperator(source_path)
    destination_path = up.remove_trailing_path_seperator(destination_path)

    source_path = os.path.abspath(source_path)
    destination_path = os.path.abspath(destination_path)

    if not os.path.exists(source_path):
        raise FileNotFoundError(
            errno.ENOENT,
            os.strerror(errno.ENOENT),
            source_path,
        )

    # check if source is dir or file (based on source path)
    if source_type == 'dir':
        if not os.path.isdir(source_path):
            raise ValueError(
                "The source path `{}` is not a directory.".format(source_path))
    elif source_type == 'file':
        if not os.path.isfile(source_path):
            raise ValueError(
                "The source path `{}` is not a file.".format(source_path))

    # extract source name from path
    source_file = os.path.basename(source_path)

    # destination is a directory
    if destination_type == 'dir':
        destination_path = os.path.join(destination_path, source_file)

    return (
        source_path,
        source_type,
        destination_path,
        destination_type,
        backup_ending,
        source_file,
    )
Ejemplo n.º 7
0
def assertStatusRegex(self, regex_status, status_object):
    """
    Asserts that status_object.payload matches the regex_status.payload and that both
    have the same status type.

    regex_status.payload can be either an FsimError or an regex expression (as a
    string).

    Exceptions
    ----------
        TypeException: if regex_status or status_object are not Status objects or if the payload is not a string.
    """
    ensure_type("regex_status", regex_status, Status)
    ensure_type("status_object", status_object, Status)

    ensure_type("status_object.payload", status_object.payload, str)
    ensure_type(
        "regex_status.payload",
        status_object.payload,
        str,
        FsimError,
        FsimError.__class__,
    )

    if isinstance(regex_status.payload, FsimError) or isinstance(
            regex_status.payload, FsimError.__class__):
        regex_string = regex_status.payload.regex_string()
    elif isinstance(regex_status.payload, str):
        regex_string = regex_status.payload

    self.assertEqual(regex_status.status, status_object.status)
    self.assertRegex(status_object.payload, regex_string)
Ejemplo n.º 8
0
def filesystem_restore(
    source_path,
    source_type,
    destination_path,
    destination_type,
    backup_ending,
    hash_value,
):
    """
    Restores a previously moved object.

    Arguments
    ---------
        source_path: path to the source
        source_type: Type of the source (a directory -> 'dir' or a file -> 'file')
        destination_path: path to the destination
        destination_type: Type of the destination (place it in a directory -> 'dir' or
             replace it -> 'file')
        backup_ending: the file ending for backup files

    """
    uty.ensure_type("hash_value", hash_value, str)

    (
        source_path,
        source_type,
        destination_path,
        destination_type,
        backup_ending,
        _,
    ) = sh.filesystem_type_check(
        source_path,
        source_type,
        destination_path,
        destination_type,
        backup_ending,
    )

    backup_path = destination_path + backup_ending

    if os.path.exists(destination_path):
        if source_type == 'dir':
            shutil.rmtree(destination_path)
        elif source_type == 'file':
            os.remove(destination_path)

    if os.path.exists(backup_path):
        os.rename(backup_path, destination_path)

    return None
Ejemplo n.º 9
0
def fs_restore(fs):
    """
    This functions restores a given `fs` by sending a command to the slave to
    restore the original state.  If the slave is offline an error will be
    returned.

    Parameters
    ----------
        fs: FilesystemModel
            A valid `FilesystemModel`.

    Raises
    ------
        SlaveOfflineError
        FilesystemNotMovedError
        TypeError:
            If `fs` is not an `FilesystemModel`
    """
    ensure_type("fs", fs, FilesystemModel)
    slave = fs.slave

    if slave.is_online:
        if not fs.is_moved:
            raise FilesystemNotMovedError(
                str(fs.name),
                str(fs.slave.name),
            )

        cmd = Command(
            method="filesystem_restore",
            source_path=fs.source_path,
            source_type=fs.source_type,
            destination_path=fs.destination_path,
            destination_type=fs.destination_type,
            backup_ending=FILE_BACKUP_ENDING,
            hash_value=fs.hash_value,
        )

        # send command to the client
        notify_slave(cmd, slave.id)

        fs.command_uuid = cmd.uuid
        fs.save()
    else:
        raise SlaveOfflineError(
            str(fs.name),
            "filesystem",
            str(fs.slave.name),
            "restore",
        )
Ejemplo n.º 10
0
def script_deep_copy(script):
    """
    This function creates a copy of a `ScriptModel` with all `ScriptGraphFiles`
    and `ScriptGraphPrograms`. The result `ScriptModle` has the same name but
    with an suffix '_copy'. If the `ScriptModel` with the suffix already exists
    then a number is appended to the name.

    Parameters
    ----------
        slave: ScriptModel
            A valid `ScriptModel`.

    Returns
    -------
        copy: ScriptModel
            The copy of the `script` with a new name.

    Raises
    ------
        TypeError:
            If `script` is not an `ScriptModel`
    """
    ensure_type("script", script, ScriptModel)
    i = 0
    copy = None

    while not copy:
        if i is 0:
            name = script.name + '_copy'
        else:
            name = script.name + '_copy_' + str(i)

        if ScriptModel.objects.filter(name=name).exists():
            i = i + 1
        else:
            copy = ScriptModel(name=name)

    copy.save()
    for file_entry in SGF.objects.filter(script_id=script.id):
        SGF(script=copy,
            index=file_entry.index,
            filesystem=file_entry.filesystem).save()

    for program_entry in SGP.objects.filter(script_id=script.id):
        SGP(script=copy,
            index=program_entry.index,
            program=program_entry.program).save()

    return copy
Ejemplo n.º 11
0
def remove_trailing_path_seperator(path):
    """
    If the last character is a path seperator, then it will be removed.

    Arguments
    ----------
        path: string

    Returns
    -------
        string
    """
    ensure_type("path", path, str)

    if path and (path[-1] == '\\' or path[-1] == '/'):
        return path[:-1]
    else:
        return path
Ejemplo n.º 12
0
def prog_stop(prog):
    """
    This function stops a `prog` by sending a command to the slave.
    The program can only be stoped if the program is currently running. If the
    slave is offline an error will be returned.

    Parameters
    ----------
        prog: ProgramModel
            A valid `ProgramModel`.

    Exception
    -------
        SlaveOfflineError
        ProgramNotRunningError
        TypeError:
            If `prog` is not an `ProgramModel`
    """
    ensure_type("prog", prog, ProgramModel)

    if prog.slave.is_online:
        if not prog.is_running:
            raise ProgramNotRunningError(str(prog.name), str(prog.slave.name))

        LOGGER.info(
            "Stoping program %s on slave %s",
            prog.name,
            prog.slave.name,
        )

        notify_slave(
            Command(
                method="execute",
                uuid=prog.programstatus.command_uuid,
            ),
            prog.slave.id,
        )
    else:
        raise SlaveOfflineError(
            str(prog.name),
            "program",
            str(prog.slave.name),
            "stop",
        )
Ejemplo n.º 13
0
def slave_wake_on_lan(slave):
    """
    This functions starts a `slave` by sending a magic (Wake-On-Lan
    package) to the `slave`.

    Parameters
    ----------
        slave: SlaveModel
            A valid `SlaveModel`.

    Raises
    ------
        TypeError:
            If `slave` is not an `SlaveModel`
    """
    ensure_type("slave", slave, SlaveModel)
    send_magic_packet(slave.mac_address)

    notify({"message": "Send start command to client `{}`".format(slave.name)})
Ejemplo n.º 14
0
def fs_delete(fs):
    """
    This functions deletes a `fs` only if `fs` is not moved.

    Parameters
    ----------
        fs: FilesystemModel
            A valid `FilesystemModel`.

    Raises
    ------
        FilesystemDeleteError
        TypeError:
            If `fs` is not an `FilesystemModel`
    """
    ensure_type("fs", fs, FilesystemModel)

    if not fs.is_moved:
        fs.delete()
    else:
        raise FilesystemDeleteError(str(fs.name), str(fs.slave.name))
Ejemplo n.º 15
0
def convert_str_to_bool(string):
    """
    Converts a string into a boolean by checking common patterns.  If no
    pattern is matching the default (False) is returned. Common string patterns
    are for the boolean true are on of ('yes', 'true', '1', 't', 'y').

    Parameters
    ----------
        string: str
            The string which will be converted.
    Returns
    -------
        bool:
            If one of the patterns was found in the string.

    Raises
    ------
        TypeError:
            If string is not a str instance.
    """
    ensure_type("string", string, str)
    return string.lower() in ('yes', 'true', '1', 't', 'y')
Ejemplo n.º 16
0
def prog_log_get(program):
    """
    This function is asking for a log for a `program` by sending a command to
    the slave. If the slave is offline an error will be returned.

    Parameters
    ----------
        program: ProgramModel
            A valid `ProgramModel`.

    Raises
    ------
        SlaveOfflineError
        LogNotExistError
        TypeError:
            If `program` is not an `ProgramModel`
    """
    ensure_type("program", program, ProgramModel)

    LOGGER.info(
        "Requesting log for program %s on slave %s",
        program.name,
        program.slave.name,
    )

    if not program.slave.is_online:
        raise SlaveOfflineError('', '', 'get_log', program.slave.name)

    if not (program.is_executed or program.is_running):
        raise LogNotExistError(program.id)

    notify_slave(
        Command(
            method="get_log",
            target_uuid=program.programstatus.command_uuid,
        ),
        program.slave.id,
    )
Ejemplo n.º 17
0
    def from_identifier(identifier, is_string):
        """
        Returns an slave based on the given `identifier` which can be an index
        or a name.

        Parameters
        ----------
            identifier: str
                Which is a `name` or `index` form the `Slave` model.
            is_string: bool
                If the `identifier` should be interpreted as a `name` or `
                index`.

        Returns
        -------
            Slave:
                If the type was correct and the slave exist.

        Raises
        ------
            Slave.DoesNotExist:
                If no slave with the given `identifier` exist.
            TypeError:
                If `identifier` and `is_string` have not the correct type.
            IdentifierError:
                If `is_string` is False and the `identifier` can not be
                transformed into an int.
        """
        ensure_type("identifier", identifier, str)
        ensure_type("is_string", is_string, bool)

        if is_string:
            return Slave.objects.get(name=identifier)
        else:
            try:
                return Slave.objects.get(id=int(identifier))
            except ValueError:
                raise IdentifierError("slave", "int", identifier)
Ejemplo n.º 18
0
    def __init__(self, index, filesystem, slave):
        ensure_type("index", index, int)

        if index < 0:
            raise PositiveNumberError(index, "index")
        self.index = index

        ensure_type("filesystem", filesystem, str, int)
        self.filesystem = filesystem

        ensure_type("slavesystem", slave, str, int)
        self.slave = slave
Ejemplo n.º 19
0
    def __init__(self, index, program, slave):
        ensure_type("index", index, int)

        if index < 0:
            raise PositiveNumberError(index, "index")
        self.index = index

        ensure_type("program", program, str, int)
        self.program = program

        ensure_type("slave", slave, str, int)
        self.slave = slave
Ejemplo n.º 20
0
    def __init__(self, name, programs, filesystems):
        ensure_type("programs", programs, list)
        ensure_type_array("programs", programs, ScriptEntryProgram)
        self.programs = programs

        ensure_type("filesystems", filesystems, list)
        ensure_type_array("filesystem", filesystems, ScriptEntryFilesystem)
        self.filesystems = filesystems

        ensure_type("name", name, str)

        self.name = name
Ejemplo n.º 21
0
 def __init__(self, error, identifier):
     ensure_type("error", error, frontend.models.Program.DoesNotExist)
     super().__init__("program", identifier)
Ejemplo n.º 22
0
 def __init__(self, error, identifier):
     ensure_type("error", error, frontend.models.Filesystem.DoesNotExist)
     super().__init__("filesystem", identifier)
Ejemplo n.º 23
0
def fs_move(fs):
    """
    This functions sends a command to slave to move the given filesystem. If
    any filesystem is at the same place it will be restored and the then `fs`
    will be moved. If the slave is offline an error will be returned.

    Parameters
    ----------
        fs: FilesystemModel
            A valid `FilesystemModel`.

    Raises
    ------
        SlaveOfflineError
        FilesystemMovedError
        TypeError:
            If `fs` is not an `FilesystemModel`
    """
    ensure_type("fs", fs, FilesystemModel)
    slave = fs.slave

    if slave.is_online:
        if fs.is_moved:
            raise FilesystemMovedError(
                str(fs.name),
                str(fs.slave.name),
            )

        if fs.destination_type == 'file':
            lookup_file_name = os.path.basename(fs.source_path)
            lookup_file = fs.destination_path
            (lookup_dir, _) = os.path.split(fs.destination_path)

        elif fs.destination_type == 'dir':
            lookup_file_name = os.path.basename(fs.source_path)
            lookup_file = os.path.join(fs.destination_path, lookup_file_name)
            lookup_dir = fs.destination_path

        query = FilesystemModel.objects.filter(
            ~Q(hash_value__exact='') & ~Q(id=fs.id)
            & ((Q(destination_path=lookup_file) & Q(destination_type='file'))
               | (Q(destination_path=lookup_dir) & Q(destination_type='dir')
                  & (Q(source_path__endswith='/' + lookup_file_name)
                     | Q(source_path__endswith='\\' + lookup_file_name)))))

        if query:
            filesystem_replace = query.get()

            first = Command(
                method="filesystem_restore",
                source_path=filesystem_replace.source_path,
                source_type=filesystem_replace.source_type,
                destination_path=filesystem_replace.destination_path,
                destination_type=filesystem_replace.destination_type,
                backup_ending=FILE_BACKUP_ENDING,
                hash_value=filesystem_replace.hash_value,
            )

            second = Command(
                method="filesystem_move",
                source_path=fs.source_path,
                source_type=fs.source_type,
                destination_path=fs.destination_path,
                destination_type=fs.destination_type,
                backup_ending=FILE_BACKUP_ENDING,
            )

            cmd = Command(
                method="chain_execution",
                commands=[dict(first), dict(second)],
            )

            filesystem_replace.command_uuid = first.uuid
            filesystem_replace.save()

            fs.command_uuid = second.uuid
            fs.save()

        else:
            cmd = Command(
                method="filesystem_move",
                source_path=fs.source_path,
                source_type=fs.source_type,
                destination_path=fs.destination_path,
                destination_type=fs.destination_type,
                backup_ending=FILE_BACKUP_ENDING,
            )

            fs.command_uuid = cmd.uuid
            fs.save()

        # send command to the client
        notify_slave(cmd, slave.id)
    else:
        raise SlaveOfflineError(
            str(fs.name),
            "filesystem",
            str(fs.slave.name),
            "move",
        )
Ejemplo n.º 24
0
 def __init__(self, error, identifier):
     ensure_type("error", error, frontend.models.Script.DoesNotExist)
     super().__init__("script", identifier)
Ejemplo n.º 25
0
def prog_start(prog):
    """
    This functions starts a `prog` by sending a command to the slave.
    The program can only be started if the program is currently not running.
    If the slave is offline an error will be returned.

    Parameters
    ----------
        prog: ProgramModel
            A valid `ProgramModel`.
    Raises
    ------
        SlaveOfflineError
        ProgramRunningError
        TypeError:
            If `prog` is not an `ProgramModel`
    """
    ensure_type("prog", prog, ProgramModel)

    if prog.slave.is_online:
        if prog.is_running:
            raise ProgramRunningError(str(prog.name), str(prog.slave.name))
        uuid = uuid4().hex

        cmd = Command(
            uuid=uuid,  # for the command
            pid=prog.id,
            own_uuid=uuid,  # for the function that gets executed
            method="execute",
            path=prog.path,
            arguments=[prog.arguments],
        )

        LOGGER.info(
            "Starting program %s on slave %s",
            prog.name,
            prog.slave.name,
        )

        # send command to the client
        notify_slave(cmd, prog.slave.id)

        # tell webinterface that the program has started
        notify({
            'program_status': 'started',
            'pid': prog.id,
        })

        # create status entry
        ProgramStatusModel(program=prog,
                           command_uuid=cmd.uuid,
                           start_time=now()).save()

        if prog.start_time > 0:
            LOGGER.debug(
                'started timeout on %s, for %d seconds',
                prog.name,
                prog.start_time,
            )
            LOGGER.debug(type(prog.start_time))
            FSIM_CURRENT_SCHEDULER.spawn(
                prog.start_time,
                timer_timeout_program,
                prog.id,
            )
        elif prog.start_time == 0:
            timer_timeout_program(prog.id)

    else:
        raise SlaveOfflineError(
            str(prog.name),
            "program",
            str(prog.slave.name),
            "start",
        )