single node,w/o ceph networking implemented

This commit is contained in:
ahmadbilalkhalid 2019-11-11 23:42:57 +05:00
commit da5a600ccb
23 changed files with 866 additions and 147 deletions

View file

@ -6,22 +6,23 @@
import errno
import os
import subprocess
import subprocess as sp
import tempfile
import time
import random
from functools import wraps
from os.path import join
from typing import Union
from decouple import config
import bitmath
import sshtunnel
from decouple import config
import qmp
from config import (WITHOUT_CEPH, VM_PREFIX, VM_DIR, IMAGE_DIR,
etcd_client, logging, request_pool,
running_vms, vm_pool)
NETWORK_PREFIX, etcd_client, logging,
request_pool, running_vms, vm_pool)
from ucloud_common.helpers import get_ipv4_address
from ucloud_common.request import RequestEntry, RequestType
from ucloud_common.vm import VMEntry, VMStatus
@ -37,13 +38,62 @@ class VM:
return "VM({})".format(self.key)
def create_dev(script, _id, dev):
assert isinstance(_id, str) and isinstance(dev, str), "_id and dev both must be string"
try:
output = sp.check_output([script, _id, dev], stderr=sp.PIPE)
except Exception as e:
print(e.stderr)
return None
else:
return output.decode("utf-8").strip()
def create_vxlan_br_tap(_id, _dev):
network_script_base = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'network')
vxlan = create_dev(script=os.path.join(network_script_base, 'create-vxlan.sh'),
_id=_id, dev=_dev)
if vxlan:
bridge = create_dev(script=os.path.join(network_script_base, 'create-bridge.sh'),
_id=_id, dev=vxlan)
if bridge:
tap = create_dev(script=os.path.join(network_script_base, 'create-tap.sh'),
_id=str(random.randint(1, 100000)), dev=bridge)
if tap:
return tap
def random_bytes(num=6):
return [random.randrange(256) for _ in range(num)]
def generate_mac(uaa=False, multicast=False, oui=None, separator=':', byte_fmt='%02x'):
mac = random_bytes()
if oui:
if type(oui) == str:
oui = [int(chunk) for chunk in oui.split(separator)]
mac = oui + random_bytes(num=6-len(oui))
else:
if multicast:
mac[0] |= 1 # set bit 0
else:
mac[0] &= ~1 # clear bit 0
if uaa:
mac[0] &= ~(1 << 1) # clear bit 1
else:
mac[0] |= 1 << 1 # set bit 1
return separator.join(byte_fmt % b for b in mac)
def get_start_command_args(
vm_entry, vnc_sock_filename: str, migration=False, migration_port=4444
vm_entry, vnc_sock_filename: str, migration=False, migration_port=4444,
):
threads_per_core = 1
vm_memory = int(bitmath.parse_string(vm_entry.specs["ram"]).to_MB())
vm_cpus = int(vm_entry.specs["cpu"])
vm_uuid = vm_entry.uuid
vm_networks = vm_entry.network
if WITHOUT_CEPH:
command = "-drive file={},format=raw,if=virtio,cache=none".format(
@ -62,8 +112,21 @@ def get_start_command_args(
if migration:
command += " -incoming tcp:0:{}".format(migration_port)
tap = None
for network_name in vm_networks:
_key = os.path.join(NETWORK_PREFIX, vm_entry.owner, network_name)
network = etcd_client.get(_key, value_in_json=True)
network_type = network.value["type"]
network_id = str(network.value["id"])
if network_type == "vxlan":
tap = create_vxlan_br_tap(network_id, "eno1")
command += " -netdev tap,id=vmnet{net_id},ifname={tap},script=no,downscript=no"\
" -device virtio-net-pci,netdev=vmnet{net_id},mac={mac}"\
.format(tap=tap, net_id=network_id, mac=generate_mac())
command += " -nic tap,model=virtio,mac={}".format(vm_entry.mac)
return command.split(" ")
@ -144,8 +207,8 @@ def create(vm_entry: VMEntry):
]
try:
subprocess.check_output(_command_to_create)
except subprocess.CalledProcessError as e:
sp.check_output(_command_to_create)
except sp.CalledProcessError as e:
if e.returncode == errno.EEXIST:
logging.debug("Image for vm %s exists", vm_entry.uuid)
# File Already exists. No Problem Continue
@ -158,7 +221,7 @@ def create(vm_entry: VMEntry):
vm_entry.status = "ERROR"
else:
try:
subprocess.check_output(_command_to_extend)
sp.check_output(_command_to_extend)
except Exception as e:
logging.exception(e)
else:
@ -199,7 +262,7 @@ def delete(vm_entry):
vm_deletion_command = ["rbd", "rm", path_without_protocol]
try:
subprocess.check_output(vm_deletion_command)
sp.check_output(vm_deletion_command)
except Exception as e:
logging.exception(e)
else: