示例#1
0
def join(connection, worker, skip_verify, disable_low_memory_guard):
    """
    Join the node to a cluster

    CONNECTION: the cluster connection endpoint in format <master>:<port>/<token>
    """
    connection_parts = connection.split("/")
    verify = not skip_verify

    if is_low_memory_guard_enabled() and disable_low_memory_guard:
        os.remove(
            os.path.expandvars("$SNAP_DATA/var/lock/low-memory-guard.lock"))

    if is_low_memory_guard_enabled() and not worker:
        print("""
This node does not have enough RAM to host the Kubernetes control plane services
and join the database quorum. You may consider joining this node as a worker instead:

    microk8s join {connection} --worker

If you would still like to join the cluster as a control plane node, use:

    microk8s join {connection} --disable-low-memory-guard

""".format(connection=connection))
        sys.exit(1)

    if is_node_running_dqlite():
        join_dqlite(connection_parts, verify, worker)
    else:
        join_etcd(connection_parts, verify)
    sys.exit(0)
示例#2
0
def reset(node, force):
    """
    Remove a node from the cluster
    """
    if is_node_running_dqlite():
        remove_dqlite_node(node, force)
    else:
        remove_node(node)
    sys.exit(0)
示例#3
0
def leave():
    """
    The node will depart from the cluster it is in.
    """
    if is_node_running_dqlite():
        if is_node_dqlite_worker():
            reset_current_dqlite_worker_installation()
        else:
            reset_current_dqlite_installation()
    else:
        reset_current_etcd_installation()
    sys.exit(0)
示例#4
0
def join(connection, worker, skip_verify):
    """
    Join the node to a cluster

    CONNECTION: the cluster connection endpoint in format <master>:<port>/<token>
    """
    connection_parts = connection.split("/")
    verify = not skip_verify
    if is_node_running_dqlite():
        join_dqlite(connection_parts, verify, worker)
    else:
        join_etcd(connection_parts, verify)
    sys.exit(0)
def print_pretty(token, check):
    default_ip, all_ips, port = get_network_info()

    print("From the node you wish to join to this cluster, run the following:")
    print(f"microk8s join {default_ip}:{port}/{token}/{check}\n")

    if is_node_running_dqlite():
        print(
            "Use the '--worker' flag to join a node as a worker not running the control plane, eg:"
        )
        print(f"microk8s join {default_ip}:{port}/{token}/{check} --worker\n")

    print(
        "If the node you are adding is not reachable through the default interface you can use one of the following:"
    )
    for ip in all_ips:
        print(f"microk8s join {ip}:{port}/{token}/{check}")
示例#6
0
def do_op(remote_op):
    """
    Perform an operation on a remote node

    :param remote_op: the operation json string
    """
    if is_node_running_dqlite():
        try:
            hostname = socket.gethostname()
            with open(callback_token_file, "r+") as fp:
                token = fp.read()

            subprocess.check_output(
                "{}/microk8s-status.wrapper --wait-ready --timeout=60".format(
                    snap_path).split())
            nodes_info = subprocess.check_output(
                "{}/microk8s-kubectl.wrapper get no -o json".format(
                    snap_path).split())
            info = json.loads(nodes_info.decode())
            for node_info in info["items"]:
                node_ip = get_internal_ip_from_get_node(node_info)
                if is_same_server(hostname, node_ip):
                    continue
                print("Configuring node {}".format(node_ip))
                # TODO: make port configurable
                node_ep = "{}:{}".format(node_ip, "25000")
                remote_op["callback"] = token.rstrip()
                # TODO: handle ssl verification
                res = requests.post(
                    "https://{}/{}/configure".format(node_ep, CLUSTER_API),
                    json=remote_op,
                    verify=False,
                )
                if res.status_code != 200:
                    print("Failed to perform a {} on node {} {}".format(
                        remote_op["action_str"], node_ep, res.status_code))
        except subprocess.CalledProcessError as e:
            print("Could not query for nodes")
            raise SystemExit(e)
        except requests.exceptions.RequestException as e:
            print("Failed to reach node.")
            raise SystemExit(e)
    else:
        with open(callback_tokens_file, "r+") as fp:
            for _, line in enumerate(fp):
                parts = line.split()
                node_ep = parts[0]
                host = node_ep.split(":")[0]
                print("Applying to node {}.".format(host))
                try:
                    # Make sure this node exists
                    subprocess.check_call(
                        "{}/microk8s-kubectl.wrapper get no {}".format(
                            snap_path, host).split(),
                        stdout=subprocess.DEVNULL,
                        stderr=subprocess.DEVNULL,
                    )
                    token = parts[1]
                    remote_op["callback"] = token
                    # TODO: handle ssl verification
                    res = requests.post(
                        "https://{}/{}/configure".format(node_ep, CLUSTER_API),
                        json=remote_op,
                        verify=False,
                    )
                    if res.status_code != 200:
                        print("Failed to perform a {} on node {}".format(
                            remote_op["action_str"], node_ep))
                except subprocess.CalledProcessError:
                    print("Node {} not present".format(host))
示例#7
0
                "name": addon,
                state: "true"
            }],
        }
        do_op(remote_op)


def usage():
    print("usage: dist_refresh_opt [OPERATION] [SERVICE] (ARGUMENT) (value)")
    print(
        "OPERATION is one of restart, update_argument, remove_argument, set_addon"
    )


if __name__ == "__main__":
    if is_node_running_dqlite() and not os.path.isfile(callback_token_file):
        # print("Single node cluster.")
        exit(0)

    if not is_node_running_dqlite() and not os.path.isfile(
            callback_tokens_file):
        print("No callback tokens file.")
        exit(1)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
示例#8
0
        if o in ("-h", "--help"):
            usage()
            sys.exit(1)
        elif o in ("-f", "--force"):
            force = True
        else:
            print("Unhandled option")
            sys.exit(1)

    if len(args) <= 0:
        print("Please provide a connection string.")
        usage()
        sys.exit(4)
    elif args[0] == "reset":
        if len(args) > 1:
            if is_node_running_dqlite():
                remove_dqlite_node(args[1], force)
            else:
                remove_node(args[1])

        else:
            if is_node_running_dqlite():
                reset_current_dqlite_installation()
            else:
                reset_current_etcd_installation()
    else:
        connection_parts = args[0].split("/")
        if is_node_running_dqlite():
            join_dqlite(connection_parts)
        else:
            join_etcd(connection_parts)