Commit 032953a6 authored by Ahmed Bilal's avatar Ahmed Bilal 💬

refactoring

parent a014220f
File mode changed from 100644 to 100755
......@@ -4,10 +4,13 @@ url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
prospector = "*"
[packages]
python-etcd3 = {editable = true,git = "https://github.com/kragniz/python-etcd3"}
pylint = "*"
python-decouple = "*"
etcd3-wrapper = "*"
[requires]
python_version = "3.7"
This diff is collapsed.
File mode changed from 100644 to 100755
all: ucloud-networking.png ucloud-vm-states.png
clean:
rm -f *.png
%.png: %.dot
dot -Tpng < $< > $@
digraph G{
rankdir=TB;
start [shape=point];
ucloud_api [style=filled,color=white];
start -> ucloud_api [label="User Requests to Start VM 'vm1'"];
subgraph cluster_common {
style=filled;
color=lightgrey;
RequestQueue [shape=rect, style=filled, color=plum1];
}
subgraph cluster_api {
style=filled;
color=lightgrey;
node [style=filled,color=white];
ucloud_api -> RequestQueue [label="RequestQueue.append(Request) "]
}
subgraph cluster_scheduler {
rankdir=RL;
style=filled;
color=lightgrey;
node [style=filled,color=white];
label="ucloud-scheduler";
PENDING_REQUESTS [shape=rect, color=peachpuff]
RequestQueue -> FindHost [label="Get StartVM Requests Only"];
FindHost -> PENDING_REQUESTS [constraint=false, color=red, label="append this requests to pending requests"];
FindHost -> RequestQueue [label="RequestQueue.append(RunVmRequest(vm='vm1'))", color=darkgreen];
PENDING_REQUESTS -> FindHost [label="On Timeout Event.\n Try to fulfil the request again"]
}
subgraph cluster_vm {
rankdir=RL;
style=filled;
color=lightgrey;
node [style=filled,color=white];
label="ucloud-vm";
VmTrash [shape=point, color=red]
RequestQueue -> HandleRequest [label="Get Requests for VM Operations"]
HandleRequest -> Running [label="RunVMRequest", color=darkgreen]
HandleRequest -> Stopped [label="ShutdownVMRequest", color=darkgreen]
HandleRequest -> VmTrash [constraint=false, color=red, label="Put error message into VM's log"]
}
}
\ No newline at end of file
digraph G {
ucloud_api [shape=box];
ucloud_router [shape=box];
ucloud_nat64 [shape=box];
{
rank = same;
ucloud_api;
ucloud_router;
ucloud_nat64;
}
ucloud_api -> REQUEST_IPV6_SLASH_64 [label="Requested by user" style="dotted"];
ucloud_api -> REQUEST_IPV4_ADDRESS [label="Requested by user" style="dotted"];
ucloud_router -> HAS_IPV6_SLASH_64 [label="Adding route" style="dotted"];
ucloud_nat64 -> HAS_IPV4_ADDRESS [label="Adding NAT64" style="dotted"];
ucloud_router -> DELETE_IPV6_SLASH_64 [label="Deleting route" style="dotted"];
ucloud_nat64 -> DELETE_IPV4_ADDRESS [label="Removing NAT64" style="dotted"];
ERROR;
ERROR -> DEFAULT;
DEFAULT -> REQUEST_IPV6_SLASH_64;
REQUEST_IPV6_SLASH_64 -> HAS_IPV6_SLASH_64 [label="If another /64 can be routed"];
REQUEST_IPV6_SLASH_64 -> ERROR [label="If no /64 can be routed"];
DEFAULT -> REQUEST_IPV4_ADDRESS;
REQUEST_IPV4_ADDRESS -> HAS_IPV4_ADDRESS;
REQUEST_IPV4_ADDRESS -> ERROR [label="If IPv4 address can be added"];
HAS_IPV6_SLASH_64 -> DELETE_IPV6_SLASH_64 -> DEFAULT;
HAS_IPV4_ADDRESS -> DELETE_IPV4_ADDRESS -> DEFAULT;
}
digraph G {
ucloud_scheduler [shape=box];
ucloud_api [shape=box];
ucloud_vm [shape=box];
ucloud_scheduler -> SCHEDULED_FOR_DEPLOY [style="dotted"];
ucloud_api -> NEW [label="Requested by user" style="dotted"];
ucloud_api -> SUSPENDED [label="Requested by user" style="dotted"];
ucloud_api -> DELETED [label="Requested by user" style="dotted"];
ucloud_vm -> RUNNING [style="dotted"];
{
rank = same;
ucloud_scheduler;
ucloud_api;
ucloud_vm;
}
NEW -> SCHEDULED_FOR_DEPLOY [label="ucloud_scheduler selects hosts"];
SCHEDULED_FOR_DEPLOY -> RUNNING [label="ucloud_vm starts VM"];
RUNNING -> SUSPENDED;
SUSPENDED -> SCHEDULED_FOR_DEPLOY;
RUNNING -> DELETED;
}
digraph G{
subgraph cluster_1 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
REQUESTED_NEW -> SCHEDULED_DEPLOY [label="assign_host()"];
SCHEDULED_DEPLOY -> REQUESTED_START [label="create_vm()"];
label="ucloud-scheduler";
}
subgraph cluster_2 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
REQUESTED_START -> RUNNING [label="start_vm()"]
RUNNING -> SUSPENDED [label="REQUESTED_SUSPEND"]
RUNNING -> RUNNING [label="REQUESTED_RESUME"]
RUNNING -> SHUTDOWN [label="REQUESTED_SHUTDOWN"]
SUSPENDED -> RUNNING [label="REQUESTED_RESUME"]
}
subgraph cluster_3 {
style=filled;
color=lightgrey;
SCHEDULED_DEPLOY -> REQUESTED_NEW [label="Host Died"]
REQUESTED_START -> KILLED [label="Host Died"]
RUNNING -> KILLED [label="Host Died OR VM Died"]
SUSPENDED -> KILLED [label="VM Died"]
SHUTDOWN -> SHUTDOWN [label="VM Died"]
label="ucloud-vm & ucloud-scheduler";
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@ import logging
from etcd3_wrapper import EtcdEntry
class SpecificEtcdEntryBase(object):
class SpecificEtcdEntryBase:
def __init__(self, e: EtcdEntry):
self.key = e.key
......@@ -24,6 +24,9 @@ class SpecificEtcdEntryBase(object):
return str(dict(self.__dict__))
# TODO: Should be removed as soon as migration
# mechanism is finalized inside ucloud
def get_ipv4_address():
# If host is connected to internet
# Return IPv4 address of machine
......
from typing import List
from .helpers import SpecificEtcdEntryBase
from .etcd3_wrapper import EtcdEntry
from helpers import SpecificEtcdEntryBase
from datetime import datetime
from os.path import join
class HostStatus(object):
class HostStatus:
alive = "ALIVE"
dead = "DEAD"
class HostEntry(SpecificEtcdEntryBase):
def __init__(self, e: EtcdEntry):
self.specs = dict()
self.hostname = ""
self.status = ""
self.last_heartbeat = ""
super().__init__(e)
specs: dict
hostname: str
status: str
last_heartbeat: str
def update_heartbeat(self):
self.status = HostStatus.alive
self.last_heartbeat = datetime.utcnow().isoformat()
......@@ -36,7 +32,7 @@ class HostEntry(SpecificEtcdEntryBase):
self.last_heartbeat = datetime.utcnow().isoformat()
class HostPool(object):
class HostPool:
def __init__(self, etcd_client, host_prefix):
self.client = etcd_client
self.prefix = host_prefix
......@@ -52,6 +48,7 @@ class HostPool(object):
v = self.client.get(key, value_in_json=True)
if v:
return HostEntry(v)
return None
def put(self, obj: HostEntry):
self.client.put(obj.key, obj.value, value_in_json=True)
......
import subprocess
class RBD(object):
@staticmethod
def ls(pool):
output = ""
try:
output = subprocess.check_output(
["rbd", "ls", pool], stderr=subprocess.PIPE
).decode("utf-8").strip()
except subprocess.CalledProcessError as e:
raise Exception(e.stderr)
return output.split("\n")
import json
from etcd3_wrapper import Etcd3Wrapper, EtcdEntry, PsuedoEtcdEntry
from decouple import config
from etcd3_wrapper import PsuedoEtcdEntry
from uuid import uuid4
from .helpers import SpecificEtcdEntryBase
from helpers import SpecificEtcdEntryBase
from os.path import join
class RequestType(object):
class RequestType:
CreateVM = "CreateVM"
ScheduleVM = "ScheduleVM"
StartVM = "StartVM"
......@@ -16,18 +18,20 @@ class RequestType(object):
class RequestEntry(SpecificEtcdEntryBase):
def __init__(self, e: EtcdEntry):
self.type = ""
super().__init__(e)
type: str
migration: bool
destination: str
uuid: str
hostname: str
@classmethod
def from_scratch(cls, **kwargs):
e = PsuedoEtcdEntry(join("/v1/request/", uuid4().hex), value=json.dumps(kwargs).encode("utf-8"),
e = PsuedoEtcdEntry(join(config("REQUEST_PREFIX"), uuid4().hex), value=json.dumps(kwargs).encode("utf-8"),
value_in_json=True)
return cls(e)
class RequestPool(object):
class RequestPool:
def __init__(self, etcd_client, request_prefix):
self.client = etcd_client
self.prefix = request_prefix
......
from contextlib import contextmanager
from datetime import datetime
from etcd3_wrapper import EtcdEntry
from .helpers import SpecificEtcdEntryBase
from helpers import SpecificEtcdEntryBase
from os.path import join
class VMStatus(object):
class VMStatus:
# Must be only assigned to brand new VM
requested_new = "REQUESTED_NEW"
......@@ -25,17 +24,17 @@ class VMStatus(object):
running = "RUNNING"
error = "ERROR" # An error occurred that cannot be resolved automatically
class VMEntry(SpecificEtcdEntryBase):
def __init__(self, e: EtcdEntry):
self.owner = ""
self.specs = dict()
self.hostname = ""
self.status = ""
self.image_uuid = ""
self.log = []
self.in_migration = False
super().__init__(e)
owner: str
specs: dict
hostname: str
status: str
image_uuid: str
log: list
in_migration: bool
@property
def uuid(self):
......@@ -61,7 +60,7 @@ class VMEntry(SpecificEtcdEntryBase):
return f"rbd:uservms/{self.uuid}"
class VmPool(object):
class VmPool:
def __init__(self, etcd_client, vm_prefix):
self.client = etcd_client
self.prefix = vm_prefix
......@@ -92,6 +91,7 @@ class VmPool(object):
v = self.client.get(key, value_in_json=True)
if v:
return VMEntry(v)
return None
def put(self, obj: VMEntry):
self.client.put(obj.key, obj.value, value_in_json=True)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment