Exemple #1
0
def tell_naming_node_im_born():
    debug_log("Wait 7 sec...")
    sleep(7)
    pub_ip = requests.request(
        "GET", "http://169.254.169.254/latest/meta-data/public-ipv4").text
    debug_log(f"Going to tell that I'm born, pub_ip = {pub_ip}")
    request_node(NAMENODE_IP, '/new_node', {'pub': pub_ip})
Exemple #2
0
def fread_command(params):
    if len(params) < 1:
        print("Please specify a file to read")
        return

    token = read_token()

    filename = os.path.basename(params[0])

    # getting right path
    params[0], result = _get_path(params[0])

    if not result:
        print("Wrong path")
        return

    res = request_node(NAMENODE_IP, "/fread", {TOKEN_KEY: token, PATH_KEY: params[0]})

    if res.status == HTTPStatus.OK:
        storage_node_ip = get_dict_from_response(res)[NODE_IP_KEY]
        full_path = get_dict_from_response(res)[FULL_PATH_KEY]

        storage_res = request_node(storage_node_ip, "/fread", {FULL_PATH_KEY: full_path})

        if storage_res.status == HTTPStatus.OK:
            file_data = get_dict_from_response(storage_res)[FILE_BYTES]
            with open(filename, "wb") as f:
                f.write(base64.decodebytes(file_data.encode()))
            print("Success!")
        else:
            print("Unsuccessful")
    else:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
Exemple #3
0
def flask_replicate():
    full_file_path = flask.request.form.get(key=FULL_PATH_KEY,
                                            default=None,
                                            type=str)
    target_node_ip = flask.request.form.get(key=NODE_IP_KEY,
                                            default=None,
                                            type=str)

    if not full_file_path or not target_node_ip:
        data = {
            MESSAGE_KEY:
            f"Missing required parameters: `{FULL_PATH_KEY}`, `{NODE_IP_KEY}`"
        }
        return flask.make_response(flask.jsonify(data),
                                   HTTPStatus.UNPROCESSABLE_ENTITY)

    file_path = get_path(full_file_path)

    try:
        with open(file_path, "rb") as f:
            file_data = str(base64.encodebytes(f.read()), 'utf-8')
    except OSError as e:
        debug_log(e.strerror)
        data = {MESSAGE_KEY: "Error on storage server"}
        return flask.make_response(flask.jsonify(data),
                                   HTTPStatus.INTERNAL_SERVER_ERROR)

    data = {FULL_PATH_KEY: full_file_path, FILE_BYTES: file_data}
    request_node(target_node_ip, '/save_replication', data)

    return flask.make_response(flask.jsonify({}), HTTPStatus.OK)
Exemple #4
0
def flask_fdelete():
    token = flask.request.form.get(key=TOKEN_KEY, default=None, type=str)
    file_path = flask.request.form.get(key=PATH_KEY, default=None, type=str)

    if not token or not file_path:
        data = {MESSAGE_KEY: f"Missing required parameters: `{TOKEN_KEY}`, `{PATH_KEY}`"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.UNPROCESSABLE_ENTITY)

    login = decode_auth_token(token)
    if not login or (type(login) == str and login not in db_auth.keys()):
        data = {MESSAGE_KEY: "The token is invalid or has expired"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    full_file_path = os.path.join(login, file_path)

    exists = full_file_path in db_user2files.lrange(login, 0, -1)
    if not exists:
        data = {MESSAGE_KEY: "The file for deleting does not exist"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.NOT_FOUND)

    for node_ip in db_file2nodes.lrange(full_file_path, 0, -1):
        res = request_node(node_ip, '/fdelete', {FULL_PATH_KEY: full_file_path})
        res = get_dict_from_response(res)
        if res is None:
            debug_log(f"Node {node_ip} did not response on /fdelete")
        db_node2files.lrem(node_ip, 0, full_file_path)

    db_user2files.lrem(login, 0, full_file_path)
    db_file2nodes.delete(full_file_path)
    db_file2size.delete(full_file_path)

    data = {MESSAGE_KEY: f"Successfully deleted the file"}
    return flask.make_response(flask.jsonify(data), HTTPStatus.OK)
Exemple #5
0
def finfo_command(params):
    if len(params) < 1:
        print("Please specify a file")
        return

    # getting right path
    params[0], result = _get_path(params[0])

    if not result:
        print("Wrong path")
        return

    token = read_token()

    params.append(token)
    params = _get_dict(params, [PATH_KEY, TOKEN_KEY])

    res = request_node(NAMENODE_IP, "/finfo", params)

    if res.status == HTTPStatus.OK:
        file_size = get_dict_from_response(res)[FILE_SIZE_KEY]
        nodes_ip = get_dict_from_response(res)[NODE_IP_KEY]
        print(f"Size of `{params[PATH_KEY]}` = {file_size} bytes\n"
              f"It's stored on {len(nodes_ip)} nodes: {nodes_ip}")
    else:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
Exemple #6
0
def flask_uploaded():
    full_file_path = flask.request.form.get(key=FULL_PATH_KEY, default=None, type=str)
    file_size = flask.request.form.get(key=FILE_SIZE_KEY, default=None, type=str)

    if not full_file_path or not file_size:
        data = {MESSAGE_KEY: f"Missing required parameters: `{FULL_PATH_KEY}`, `{FILE_SIZE_KEY}`"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.UNPROCESSABLE_ENTITY)

    login = full_file_path.split('/')[0]

    db_file2size.set(full_file_path, file_size)
    if full_file_path not in db_user2files.lrange(login, 0, -1):
        db_user2files.lpush(login, full_file_path)

    source_node_ip = flask.request.environ.get('HTTP_X_REAL_IP', flask.request.remote_addr)

    nodes_with_obsolete_files = db_file2nodes.lrange(full_file_path, 0, -1)
    if source_node_ip in nodes_with_obsolete_files:
        nodes_with_obsolete_files.remove(source_node_ip)
    else:
        db_node2files.lpush(source_node_ip, full_file_path)
        db_file2nodes.lpush(full_file_path, source_node_ip)

    for node_ip in nodes_with_obsolete_files:
        res = request_node(node_ip, '/fdelete', {FULL_PATH_KEY: full_file_path})
        res = get_dict_from_response(res)
        if res is None:
            debug_log(f"Node {node_ip} did not response on /fdelete")
        db_node2files.lrem(node_ip, 0, full_file_path)
        db_file2nodes.lrem(full_file_path, 0, node_ip)

    replicate(full_file_path=full_file_path)

    data = {MESSAGE_KEY: 'OK, uploaded.'}
    return flask.make_response(flask.jsonify(data), HTTPStatus.OK)
Exemple #7
0
def rdir_command(params):
    if len(params) < 1:
        print("Please specify a directory to read")
        return

    # getting right path
    params[0], result = _get_path(params[0])

    if not result:
        print("Wrong path")
        return

    token = read_token()

    params.append(token)
    params = _get_dict(params, [PATH_KEY, TOKEN_KEY])

    res = request_node(NAMENODE_IP, "/rdir", params)

    if res.status == HTTPStatus.OK:
        dir_list = get_dict_from_response(res)[DIR_LIST_KEY]
        for l in dir_list:
            print(f" -- {l}")
    else:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
Exemple #8
0
def _auth(params, action):
    # login and registration with getting token
    if len(params) < 2:
        print("Specify login and password please.")
        return
    
    login = params[0]
    password = params[1]
    
    if login == "" or password == "":
        print("Please give me non-empty login and password")
        return
    
    encrypted_pass = hashlib.md5(password.encode('utf-8')).hexdigest()
    data = {LOGIN_KEY: login, ENCRYPTED_PASS_KEY: encrypted_pass}
    res = request_node(NAMENODE_IP, f"/{action}", data)

    if res.status == HTTPStatus.OK:
        token = get_dict_from_response(res)[TOKEN_KEY]
        save_token(token)
        _update_current_path(START_PATH)
        print("Success!\nYou were logged in.")
    else:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
Exemple #9
0
def flask_ddir():
    token = flask.request.form.get(key=TOKEN_KEY, default=None, type=str)
    dir_path = flask.request.form.get(key=PATH_KEY, default=None, type=str)
    force = flask.request.form.get(key=FORCE_KEY, default=None, type=str)

    if not token or dir_path is None or force is None:
        data = {MESSAGE_KEY: f"Missing required parameters: `{TOKEN_KEY}`, `{PATH_KEY}`, `{FORCE_KEY}`"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.UNPROCESSABLE_ENTITY)

    login = decode_auth_token(token)
    if not login or (type(login) == str and login not in db_auth.keys()):
        data = {MESSAGE_KEY: "The token is invalid or has expired"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    dir_path = dir_path[:-1] if dir_path and dir_path[-1] == '/' else dir_path

    if not dir_path:
        data = {MESSAGE_KEY: "Can't delete the root directory"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    full_dir_path = os.path.join(login, dir_path)

    if full_dir_path not in db_user2folders.lrange(login, 0, -1):
        data = {MESSAGE_KEY: "The folder for deleting does not exist"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.NOT_FOUND)

    inner_files_path_list = [full_path for full_path in db_user2files.lrange(login, 0, -1) if
                             full_path.startswith(full_dir_path + '/')]
    inner_folders_path_list = [full_path for full_path in db_user2folders.lrange(login, 0, -1)
                               if full_path.startswith(full_dir_path + '/')]

    if force == 'False' and (inner_files_path_list or inner_folders_path_list):
        data = {MESSAGE_KEY: 'The directory contains files. `force=true` to delete'}
        return flask.make_response(flask.jsonify(data), HTTPStatus.NOT_ACCEPTABLE)

    db_user2folders.lrem(login, 0, full_dir_path)
    for inner_dir in inner_folders_path_list:
        db_user2folders.lrem(login, 0, inner_dir)

    nodes_ip = set()
    for inner_file in inner_files_path_list:
        db_file2size.delete(inner_file)
        db_user2files.lrem(login, 0, inner_file)

        for node_ip in db_file2nodes.lrange(inner_file, 0, -1):
            db_file2nodes.lrem(inner_file, 0, node_ip)
            db_node2files.lrem(node_ip, 0, inner_file)
            nodes_ip.add(node_ip)

    for node_ip in list(nodes_ip):
        res = request_node(node_ip, '/ddir', {FULL_PATH_KEY: full_dir_path})
        res = get_dict_from_response(res)
        if res is None:
            debug_log(f"Node {node_ip} did not response on /ddir ({full_dir_path})")

    data = {MESSAGE_KEY: 'Successfully deleted the directory'}
    return flask.make_response(flask.jsonify(data), HTTPStatus.OK)
Exemple #10
0
def _dir_exists(path):
    token = read_token()

    data = {TOKEN_KEY: token, PATH_KEY: path}
    res = request_node(NAMENODE_IP, "/dir_exists", data)

    if res.status == HTTPStatus.OK:
        return True, get_dict_from_response(res)[MESSAGE_KEY]
    else:
        return False, get_dict_from_response(res)[MESSAGE_KEY]
Exemple #11
0
def fwrite_command(params):
    if len(params) < 1:
        print("Please specify a file to write to")
        return

    token = read_token()

    filename = params[0]

    if not os.path.exists(filename):
        print("There is no such file")
        return

    # getting right path
    params[0], result = _get_path(os.path.basename(params[0]))

    if not result:
        print("Wrong path")
        return

    res = request_node(NAMENODE_IP, "/fwrite", {TOKEN_KEY: token, PATH_KEY: params[0]})

    if res.status == HTTPStatus.OK:
        storage_node_ip = get_dict_from_response(res)[NODE_IP_KEY]

        with open(filename, 'rb') as f:
            file_data = f.read()

        storage_res = request_node(storage_node_ip, "/fwrite",
                                   {FULL_PATH_KEY: get_dict_from_response(res)[FULL_PATH_KEY],
                                    FILE_BYTES: str(base64.encodebytes(file_data), 'utf-8')})

        if storage_res.status == HTTPStatus.OK:
            print("Success!")
        else:
            msg = get_dict_from_response(storage_res)[MESSAGE_KEY]
            print(msg)
    else:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
Exemple #12
0
def flask_fmove():
    token = flask.request.form.get(key=TOKEN_KEY, default=None, type=str)
    file_path = flask.request.form.get(key=PATH_KEY, default=None, type=str)
    file_destination_path = flask.request.form.get(key=PATH_DESTINATION_KEY, default=None, type=str)

    if not token or not file_path or file_destination_path is None:
        data = {MESSAGE_KEY: f"Missing required parameters: `{TOKEN_KEY}`, `{PATH_KEY}`, `{PATH_DESTINATION_KEY}`"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.UNPROCESSABLE_ENTITY)

    login = decode_auth_token(token)
    if not login or (type(login) == str and login not in db_auth.keys()):
        data = {MESSAGE_KEY: "The token is invalid or has expired"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    if not os.path.basename(file_destination_path):
        data = {MESSAGE_KEY: "The destination file name is empty"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    full_file_path = os.path.join(login, file_path)
    full_file_destination_path = os.path.join(login, file_destination_path)

    if full_file_path not in db_user2files.lrange(login, 0, -1):
        data = {MESSAGE_KEY: "The source file doesn't exist"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    if os.path.dirname(full_file_destination_path) not in db_user2folders.lrange(login, 0, -1):
        data = {MESSAGE_KEY: "Can't move the file. Destination folder doesn't exist"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    for node_ip in db_file2nodes.lrange(full_file_path, 0, -1):
        res = request_node(node_ip, '/fmove', {FULL_PATH_KEY: full_file_path,
                                               FULL_PATH_DESTINATION_KEY: full_file_destination_path})
        res = get_dict_from_response(res)
        if res is None:
            debug_log(f"Node {node_ip} did not response on /fmove")
        else:
            db_node2files.lrem(node_ip, 0, full_file_path)
            db_node2files.lpush(node_ip, full_file_destination_path)

            db_file2nodes.lrem(full_file_path, 0, node_ip)
            db_file2nodes.lpush(full_file_destination_path, node_ip)

    db_user2files.lrem(login, 0, full_file_path)
    db_user2files.lpush(login, full_file_destination_path)

    db_file2size.set(full_file_destination_path, db_file2size.get(full_file_path))
    db_file2size.delete(full_file_path)

    data = {MESSAGE_KEY: f"Successfully moved the file"}
    return flask.make_response(flask.jsonify(data), HTTPStatus.OK)
Exemple #13
0
def init(login):
    data_for_node = {LOGIN_KEY: login}
    for node_ip in db_congestion.keys():
        res = request_node(node_ip, '/init', data_for_node)
        res = get_dict_from_response(res)
        debug_log(f"/init - node {node_ip} responded wih {res}")

    full_file_paths = db_user2files.lrange(login, 0, -1)
    was_initialised_before = db_user2files.delete(login)
    for full_file_path in full_file_paths:
        db_file2size.delete(full_file_path)
        nodes_containing_file = db_file2nodes.lrange(full_file_path, 0, -1)
        db_file2nodes.delete(full_file_path)
        db_user2files.delete(full_file_path)
        for node in nodes_containing_file:
            db_node2files.lrem(node, 1, full_file_path)
            res = request_node(node, '/fdelete', {FULL_PATH_KEY: full_file_path})
            res = get_dict_from_response(res)
            if res is None:
                debug_log(f"Node {node_ip} did not response on /fdelete")
    db_user2folders.delete(login)
    db_user2folders.lpush(login, login)
    return was_initialised_before
Exemple #14
0
def ddir_command(params):
    if len(params) < 1:
        print("Please specify a directory to delete")
        return

    # getting right path
    params[0], result = _get_path(params[0])

    if not result:
        print("Wrong path")
        return

    if _get_current_path() == params[0] or params[0] == '':
        print("Denied")
        return

    token = read_token()

    res = request_node(NAMENODE_IP, "/ddir", {TOKEN_KEY: token, PATH_KEY: params[0], FORCE_KEY: False})

    if res.status == HTTPStatus.OK:
        print("Success!")
    elif res.status == HTTPStatus.NOT_ACCEPTABLE:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
        answer = input("Delete? [Y/n]: ")
        if answer.lower() == "y":
            res = request_node(NAMENODE_IP, "/ddir", {TOKEN_KEY: token, PATH_KEY: params[0], FORCE_KEY: True})
            if res.status == HTTPStatus.OK:
                print("Success!")
            else:
                msg = get_dict_from_response(res)[MESSAGE_KEY]
                print(msg)
    else:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
Exemple #15
0
 def ping_nodes():
     for node_ip in db_congestion.keys():
         if node_ip not in non_responsive_count:
             non_responsive_count[node_ip] = 0
         res = request_node(node_ip, '/ping', {})
         res = get_dict_from_response(res)
         if res is None:
             non_responsive_count[node_ip] += 1
             debug_log(f"Node {node_ip} did not response {non_responsive_count[node_ip]} times")
             if non_responsive_count[node_ip] == MAX_PING_TRIES:
                 remove_node(node_ip)
                 del non_responsive_count[node_ip]
         else:
             debug_log(f"Pinging node {node_ip} - {res}")
             db_congestion.set(node_ip, res[CONGESTION_KEY])
Exemple #16
0
def _command(params, keys, action):
    # executing command with token
    token = read_token()

    params.append(token)
    keys.append(TOKEN_KEY)

    params = _get_dict(params, keys)

    res = request_node(NAMENODE_IP, f"/{action}", params)

    if res.status == HTTPStatus.OK:
        print("Success!")
    else:
        msg = get_dict_from_response(res)[MESSAGE_KEY]
        print(msg)
Exemple #17
0
def flask_fwrite():
    full_file_path = flask.request.form.get(key=FULL_PATH_KEY,
                                            default=None,
                                            type=str)
    file_bytes = flask.request.form.get(key=FILE_BYTES, default=None, type=str)

    if not full_file_path or file_bytes is None:
        data = {
            MESSAGE_KEY:
            f"Missing required parameters: `{FULL_PATH_KEY}`, `{FILE_BYTES}`"
        }
        return flask.make_response(flask.jsonify(data),
                                   HTTPStatus.UNPROCESSABLE_ENTITY)

    file_path = get_path(full_file_path)
    file_bytes = base64.decodebytes(file_bytes.encode())

    try:
        all_dirs = full_file_path.split("/")[:-1]
        dir_path = ROOT
        for directory in all_dirs:
            dir_path = os.path.join(dir_path, directory)
            if not os.path.exists(dir_path):
                os.mkdir(dir_path)
        # writeing to file
        with open(file_path, 'wb') as f:
            f.write(file_bytes)
    except OSError as e:
        debug_log(e.strerror)
        data = {MESSAGE_KEY: "Error on the server"}
        return flask.make_response(flask.jsonify(data),
                                   HTTPStatus.INTERNAL_SERVER_ERROR)

    data = {FULL_PATH_KEY: full_file_path, FILE_SIZE_KEY: len(file_bytes)}
    res = request_node(NAMENODE_IP, '/uploaded', data)
    if res.status != HTTPStatus.OK:
        data = {MESSAGE_KEY: get_dict_from_response(res)[MESSAGE_KEY]}
        return flask.make_response(flask.jsonify(data), HTTPStatus.OK)

    data = {MESSAGE_KEY: "OK"}
    return flask.make_response(flask.jsonify(data), HTTPStatus.OK)
Exemple #18
0
def replicate(full_file_path: str):
    source_nodes_ip = db_file2nodes.lrange(full_file_path, 0, -1)
    assert source_nodes_ip

    target_nodes_ip = db_congestion.keys()
    target_nodes_ip = list(set(target_nodes_ip) - set(source_nodes_ip))

    congestions = [(node_ip, db_congestion.get(node_ip)) for node_ip in target_nodes_ip]
    congestions = sorted(congestions, key=lambda x: x[1])
    target_nodes_ip = [congestion[0] for congestion in congestions[:REPLICATION_FACTOR - len(source_nodes_ip)]]
    debug_log(f"Going to replicate {full_file_path} from {source_nodes_ip} "
              f"to nodes with lowest congestion: {target_nodes_ip}")

    for target_node_ip in target_nodes_ip:
        res = request_node(source_nodes_ip[0], '/replicate', {FULL_PATH_KEY: full_file_path,
                                                              NODE_IP_KEY: target_node_ip})
        res = get_dict_from_response(res)
        if res is None:
            debug_log(f"Node {source_nodes_ip[0]} did not response on /replicate")
        else:
            db_file2nodes.lpush(full_file_path, target_node_ip)
            db_node2files.lpush(target_node_ip, full_file_path)
Exemple #19
0
def flask_fcreate():
    token = flask.request.form.get(key=TOKEN_KEY, default=None, type=str)
    file_path = flask.request.form.get(key=PATH_KEY, default=None, type=str)

    if not token or not file_path:
        data = {MESSAGE_KEY: f"Missing required parameters: `{TOKEN_KEY}`, `{PATH_KEY}`"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.UNPROCESSABLE_ENTITY)

    login = decode_auth_token(token)
    if not login or (type(login) == str and login not in db_auth.keys()):
        data = {MESSAGE_KEY: "The token is invalid or has expired"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    full_file_path = os.path.join(login, file_path)

    if os.path.dirname(full_file_path) not in db_user2folders.lrange(login, 0, -1):
        data = {MESSAGE_KEY: "Can't create the file. Folder doesn't exist"}
        return flask.make_response(flask.jsonify(data), HTTPStatus.FORBIDDEN)

    congestions = [(node_ip, db_congestion.get(node_ip)) for node_ip in db_congestion.keys()]
    congestions = sorted(congestions, key=lambda x: x[1])
    nodes = [congestion[0] for congestion in congestions[:REPLICATION_FACTOR]]
    debug_log(f"/fcreate - nodes with lowest congestion: {nodes}")

    data_for_node = {FULL_PATH_KEY: full_file_path}
    for node_ip in nodes:
        res = request_node(node_ip, '/fcreate', data_for_node)
        res = get_dict_from_response(res)
        debug_log(f"/fcreate - storage node {node_ip} response: {res}")
        db_node2files.lpush(node_ip, full_file_path)

    db_user2files.lpush(login, full_file_path)
    db_file2nodes.lpush(full_file_path, *nodes)
    db_file2size.set(full_file_path, 0)

    data = {MESSAGE_KEY: f"Successfully created the file"}
    return flask.make_response(flask.jsonify(data), HTTPStatus.OK)