diff options
Diffstat (limited to 'vicn/resource')
-rw-r--r-- | vicn/resource/central.py | 91 | ||||
-rw-r--r-- | vicn/resource/linux/certificate.py | 9 | ||||
-rw-r--r-- | vicn/resource/linux/keypair.py | 71 | ||||
-rw-r--r-- | vicn/resource/linux/link.py | 75 | ||||
-rw-r--r-- | vicn/resource/linux/net_device.py | 3 | ||||
-rw-r--r-- | vicn/resource/linux/physical.py | 40 | ||||
-rw-r--r-- | vicn/resource/lxd/lxd_hypervisor.py | 12 | ||||
-rw-r--r-- | vicn/resource/node.py | 8 | ||||
-rw-r--r-- | vicn/resource/ns3/emulated_channel.py | 12 | ||||
-rw-r--r-- | vicn/resource/ns3/emulated_lte_channel.py | 10 |
10 files changed, 193 insertions, 138 deletions
diff --git a/vicn/resource/central.py b/vicn/resource/central.py index 73a43478..6f3c680b 100644 --- a/vicn/resource/central.py +++ b/vicn/resource/central.py @@ -16,8 +16,9 @@ # limitations under the License. # -import networkx as nx import logging +import networkx as nx +import os from netmodel.model.type import String from netmodel.util.misc import pairwise @@ -54,7 +55,7 @@ CMD_NAT = '\n'.join([ # For containers CMD_IP_FORWARD = 'echo 1 > /proc/sys/net/ipv4/ip_forward' -HOST_FILE_PATH = "/etc/hosts.vicn" +HOST_FILE = "hosts.vicn" #------------------------------------------------------------------------------ # Routing strategies @@ -162,29 +163,29 @@ def _get_l2_graph(manager, with_managed = False): if G.has_edge(src.node._state.uuid, dst.node._state.uuid): continue - map_node_interface = { src.node._state.uuid : src._state.uuid, + map_node_interface = { src.node._state.uuid : src._state.uuid, dst.node._state.uuid: dst._state.uuid} - G.add_edge(src.node._state.uuid, dst.node._state.uuid, + G.add_edge(src.node._state.uuid, dst.node._state.uuid, map_node_interface = map_node_interface) else: # This is for a normal Channel for src_it in range(0,len(channel.interfaces)): src = channel.interfaces[src_it] - # Iterate over the remaining interface to create all the + # Iterate over the remaining interface to create all the # possible combination for dst_it in range(src_it+1,len(channel.interfaces)): dst = channel.interfaces[dst_it] - - if not with_managed and (not src.managed or + + if not with_managed and (not src.managed or not dst.managed): continue if G.has_edge(src.node._state.uuid, dst.node._state.uuid): continue - map_node_interface = { - src.node._state.uuid : src._state.uuid, + map_node_interface = { + src.node._state.uuid : src._state.uuid, dst.node._state.uuid: dst._state.uuid} - G.add_edge(src.node._state.uuid, dst.node._state.uuid, + G.add_edge(src.node._state.uuid, dst.node._state.uuid, map_node_interface = map_node_interface) return G @@ -198,9 +199,9 @@ def _get_icn_graph(manager): other_node = other_face.node if G.has_edge(node._state.uuid, other_node._state.uuid): continue - map_node_face = { node._state.uuid: face._state.uuid, + map_node_face = { node._state.uuid: face._state.uuid, other_node._state.uuid: other_face._state.uuid } - G.add_edge(node._state.uuid, other_node._state.uuid, + G.add_edge(node._state.uuid, other_node._state.uuid, map_node_face = map_node_face) return G @@ -224,7 +225,9 @@ class IPAssignment(Resource): raise ResourceNotFound def __subresources__(self): - self.host_file = TextFile(node = None, filename = HOST_FILE_PATH, + basedir = os.path.dirname(self._state.manager._base) + self.host_file = TextFile(node = None, + filename = os.path.join(basedir, HOST_FILE), overwrite = True) return self.host_file @@ -241,13 +244,13 @@ class IPAssignment(Resource): # We sort nodes by names for IP assignment. This code ensures that # interfaces on the same channel get consecutive IP addresses. That # way, we can assign /31 on p2p channels. - channels = sorted(self._state.manager.by_type(Channel), + channels = sorted(self._state.manager.by_type(Channel), key = lambda x : x.get_sortable_name()) - channels.extend(sorted(self._state.manager.by_type(Node), + channels.extend(sorted(self._state.manager.by_type(Node), key = lambda node : node.name)) host_file_content = "" - + # Dummy code to start IP addressing on an even number for /31 ip = AddressManager().get_ip(None) if int(ip[-1]) % 2 == 0: @@ -256,7 +259,7 @@ class IPAssignment(Resource): for channel in channels: # Sort interfaces in a deterministic order to ensure consistent # addressing across restarts of the tool - interfaces = sorted(channel.interfaces, + interfaces = sorted(channel.interfaces, key = lambda x : x.device_name) for interface in interfaces: @@ -279,7 +282,7 @@ class IPAssignment(Resource): host_file_content += '# {} {} {}\n'.format( interface.node.name, interface.device_name, ip) if interface == interface.node.host_interface: - host_file_content += '{} {}\n'.format(ip, + host_file_content += '{} {}\n'.format(ip, interface.node.name) self.host_file.content = host_file_content @@ -339,7 +342,7 @@ class IPRoutes(Resource): G = _get_l2_graph(self._state.manager) origins = self._get_ip_origins() - + # node -> list(origins for which we have routes) ip_routes = dict() @@ -347,7 +350,7 @@ class IPRoutes(Resource): routes = list() for src, prefix, dst in strategy(G, origins): data = G.get_edge_data(src, dst) - + map_ = data['map_node_interface'] next_hop_interface = map_[src] @@ -356,7 +359,7 @@ class IPRoutes(Resource): src_node = self._state.manager.by_uuid(src) mac_addr = None - if ((hasattr(next_hop_ingress, 'vpp') and + if ((hasattr(next_hop_ingress, 'vpp') and next_hop_ingress.vpp is not None) or (hasattr(src_node, 'vpp') and src_node.vpp is not None)): mac_addr = next_hop_ingress.mac_address @@ -366,15 +369,15 @@ class IPRoutes(Resource): ip_routes[src_node] = list() if prefix in ip_routes[src_node]: continue - + if prefix == next_hop_ingress.ip_address: # Direct route on src_node.name : # route add [prefix] dev [next_hop_interface_.device_name] - route = IPRoute(node = src_node, + route = IPRoute(node = src_node, managed = False, owner = self, ip_address = prefix, - mac_address = mac_addr, + mac_address = mac_addr, interface = next_hop_interface) else: # We need to be sure we have a route to the gw from the node @@ -387,11 +390,11 @@ class IPRoutes(Resource): interface = next_hop_interface) ip_routes[src_node].append(next_hop_ingress.ip_address) pre_routes.append(pre_route) - - # Route on src_node.name: + + # Route on src_node.name: # route add [prefix] dev [next_hop_interface_.device_name] # via [next_hop_ingress.ip_address] - route = IPRoute(node = src_node, + route = IPRoute(node = src_node, managed = False, owner = self, ip_address = prefix, @@ -407,7 +410,7 @@ class IPRoutes(Resource): IP routing strategy : direct routes only """ routes = list() - G = _get_l2_graph(self._state.manager) + G = _get_l2_graph(self._state.manager) for src_node_uuid, dst_node_uuid, data in G.edges_iter(data = True): src_node = self._state.manager.by_uuid(src_node_uuid) dst_node = self._state.manager.by_uuid(dst_node_uuid) @@ -423,7 +426,7 @@ class IPRoutes(Resource): dst_node.name, dst.device_name, dst.ip_address, src_node.name, src.device_name, src.ip_address)) - route = IPRoute(node = src_node, + route = IPRoute(node = src_node, managed = False, owner = self, ip_address = dst.ip_address, @@ -431,7 +434,7 @@ class IPRoutes(Resource): interface = src) routes.append(route) - route = IPRoute(node = dst_node, + route = IPRoute(node = dst_node, managed = False, owner = self, ip_address = src.ip_address, @@ -498,14 +501,14 @@ class ICNFaces(Resource): owner = self, protocol = protocol, src_nic = src, - dst_mac = dst.mac_address) + dst_mac = dst.mac_address) dst_face = L2Face(node = dst_node, owner = self, protocol = protocol, src_nic = dst, dst_mac = src.mac_address) - elif protocol in (FaceProtocol.tcp4, FaceProtocol.tcp6, + elif protocol in (FaceProtocol.tcp4, FaceProtocol.tcp6, FaceProtocol.udp4, FaceProtocol.udp6): src_face = L4Face(node = src_node, owner = self, @@ -513,14 +516,14 @@ class ICNFaces(Resource): src_ip = src.ip_address, dst_ip = dst.ip_address, src_port = TMP_DEFAULT_PORT, - dst_port = TMP_DEFAULT_PORT) + dst_port = TMP_DEFAULT_PORT) dst_face = L4Face(node = dst_node, owner = self, protocol = protocol, src_ip = dst.ip_address, dst_ip = src.ip_address, src_port = TMP_DEFAULT_PORT, - dst_port = TMP_DEFAULT_PORT) + dst_port = TMP_DEFAULT_PORT) else: raise NotImplementedError @@ -583,7 +586,7 @@ class ICNRoutes(Resource): routes = list() for src, prefix, dst in strategy(G, origins): data = G.get_edge_data(src, dst) - + map_ = data['map_node_face'] next_hop_face = map_[src] @@ -675,9 +678,9 @@ class ContainerSetup(Resource): route_gw.node.routing_table.routes << route_gw # c) dns - dns_server_entry = DnsServerEntry(node = self.container, + dns_server_entry = DnsServerEntry(node = self.container, owner = self, - ip_address = self.container.node.bridge.ip_address, + ip_address = self.container.node.bridge.ip_address, interface_name = self.container.host_interface.device_name) return dns_server_entry @@ -710,7 +713,7 @@ class ContainersSetup(Resource): if len(containers) == 0: return None - container_resources = [ContainerSetup(owner = self, container = c) + container_resources = [ContainerSetup(owner = self, container = c) for c in containers] return Resource.__concurrent__(*container_resources) @@ -737,7 +740,7 @@ class CentralIP(Resource): def __subresources__(self): ip_assign = IPAssignment(owner=self) containers_setup = ContainersSetup(owner=self) - ip_routes = IPRoutes(owner = self, + ip_routes = IPRoutes(owner = self, routing_strategy = self.ip_routing_strategy) return ip_assign > (ip_routes | containers_setup) @@ -758,10 +761,10 @@ class CentralICN(Resource): """ # Choices: spt, max_flow - icn_routing_strategy = Attribute(String, + icn_routing_strategy = Attribute(String, description = 'ICN routing strategy', - default = 'spt') - face_protocol = Attribute(String, + default = 'spt') + face_protocol = Attribute(String, description = 'Protocol used to create faces', default = 'ether') @@ -777,8 +780,8 @@ class CentralICN(Resource): return ('CentralIP',) def __subresources__(self): - icn_faces = ICNFaces(owner = self, protocol_name = self.face_protocol) - icn_routes = ICNRoutes(owner = self, + icn_faces = ICNFaces(owner = self, protocol_name = self.face_protocol) + icn_routes = ICNRoutes(owner = self, routing_strategy = self.icn_routing_strategy) return icn_faces > icn_routes diff --git a/vicn/resource/linux/certificate.py b/vicn/resource/linux/certificate.py index e8750dff..7f9b8a74 100644 --- a/vicn/resource/linux/certificate.py +++ b/vicn/resource/linux/certificate.py @@ -31,6 +31,8 @@ DEFAULT_SUBJECT = '/CN=www.cisco.com/L=Paris/O=Cisco/C=FR' CMD_CREATE='\n'.join([ '# Generate a new certificate', + 'mkdir -p $(dirname {self.key})', + 'mkdir -p $(dirname {self.cert})', 'openssl req -x509 -newkey rsa:' + DEFAULT_RSA_LENGTH + ' -keyout {self.key} -out {self.cert} -subj ' + DEFAULT_SUBJECT + ' -nodes' ]) @@ -40,9 +42,6 @@ class Certificate(Resource): Resource: Certificate Implements a SSL certificate. - - Todo: - - ideally, this should be implemented as a pair of tightly coupled files. """ node = Attribute(Node, description = 'Node on which the certificate is created', @@ -53,6 +52,10 @@ class Certificate(Resource): key = Attribute(String, description = 'Key path', mandatory = True) + #-------------------------------------------------------------------------- + # Resource lifecycle + #-------------------------------------------------------------------------- + @inline_task def __initialize__(self): self._cert_file = File(node = Reference(self, 'node'), diff --git a/vicn/resource/linux/keypair.py b/vicn/resource/linux/keypair.py new file mode 100644 index 00000000..a81a40d4 --- /dev/null +++ b/vicn/resource/linux/keypair.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2017 Cisco and/or its affiliates. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os.path + +from netmodel.model.type import String +from vicn.core.attribute import Attribute, Multiplicity, Reference +from vicn.core.exception import ResourceNotFound +from vicn.core.resource import Resource +from vicn.core.task import task, inline_task, BashTask +from vicn.resource.linux.file import File +from vicn.resource.node import Node + +CMD_CREATE=''' +mkdir -p {dirname} +ssh-keygen -t rsa -N "" -f {self.key} +''' + +class Keypair(Resource): + """ + Resource: Keypair + + Implements a SSH keypair + """ + node = Attribute(Node, + description = 'Node on which the certificate is created', + mandatory = True, + multiplicity = Multiplicity.ManyToOne) + key = Attribute(String, description = 'Key path', + mandatory = True) + + #-------------------------------------------------------------------------- + # Resource lifecycle + #-------------------------------------------------------------------------- + + @inline_task + def __initialize__(self): + self._pubkey_file = File(node = Reference(self, 'node'), + filename = self.key + '.pub', + managed = False) + self._key_file = File(node = Reference(self, 'node'), + filename = self.key, + managed = False) + + def __get__(self): + return self._pubkey_file.__get__() | self._key_file.__get__() + + def __create__(self): + return BashTask(None, CMD_CREATE, { + 'dirname': os.path.dirname(self.key), + 'self': self}) + + def __delete__(self): + return self._pubkey_file.__delete__() | self._key_file.__delete__() + + diff --git a/vicn/resource/linux/link.py b/vicn/resource/linux/link.py index 4304a948..a4771f9c 100644 --- a/vicn/resource/linux/link.py +++ b/vicn/resource/linux/link.py @@ -42,8 +42,8 @@ CMD_DELETE_IF_EXISTS='ip link show {interface.device_name} && ' \ CMD_CREATE=''' # Create veth pair in the host node ip link add name {tmp_src} type veth peer name {tmp_dst} -ip link set dev {tmp_src} netns {pid[0]} name {interface.src.device_name} -ip link set dev {tmp_dst} netns {pid[1]} name {interface.dst.device_name} +ip link set dev {tmp_src} netns {pid[0]} name {interface._src.device_name} +ip link set dev {tmp_dst} netns {pid[1]} name {interface._dst.device_name} ''' CMD_UP=''' ip link set dev {interface.device_name} up @@ -61,9 +61,6 @@ class Link(Channel): the current implementation. """ - src = Attribute(Interface, description = 'Source interface') - dst = Attribute(Interface, description = 'Destination interface') - capacity = Attribute(Integer, description = 'Link capacity (Mb/s)') delay = Attribute(String, description = 'Link propagation delay') @@ -73,29 +70,29 @@ class Link(Channel): mandatory = True) def __init__(self, *args, **kwargs): - assert 'src' not in kwargs and 'dst' not in kwargs assert 'src_node' in kwargs and 'dst_node' in kwargs + self._src = None + self._dst = None super().__init__(*args, **kwargs) @inline_task def __initialize__(self): - # We create two managed net devices that are pre-setup # but the resource manager has to take over for IP addresses etc. # Being done in initialize, those attributes won't be considered as # dependencies and will thus not block the resource state machine. - self.src = NonTapBaseNetDevice(node = self.src_node, + self._src = NonTapBaseNetDevice(node = self.src_node, device_name = self.dst_node.name, channel = self, capacity = self.capacity, - owner = self.owner) - self.dst = NonTapBaseNetDevice(node = self.dst_node, + owner = self) + self._dst = NonTapBaseNetDevice(node = self.dst_node, device_name = self.src_node.name, channel = self, capacity = self.capacity, - owner = self.owner) - self.dst.remote = self.src - self.src.remote = self.dst + owner = self) + self._dst.remote = self._src + self._src.remote = self._dst #-------------------------------------------------------------------------- # Internal methods @@ -104,21 +101,8 @@ class Link(Channel): async def _commit(self): manager = self._state.manager - # We mark the src and dst interfaces created because we are pre-setting - # them up in __create__ using a VethPair - # We go through both INITIALIZED and CREATED stats to raise the proper - # events and satisfy any eventual wait_* command. - await manager._set_resource_state(self.src, ResourceState.INITIALIZED) - await manager._set_resource_state(self.dst, ResourceState.INITIALIZED) - await manager._set_resource_state(self.src, ResourceState.CREATED) - await manager._set_resource_state(self.dst, ResourceState.CREATED) - - # We mark the attribute clean so that it is not updated - await manager._set_attribute_state(self, 'src', AttributeState.CLEAN) - await manager._set_attribute_state(self, 'dst', AttributeState.CLEAN) - - manager.commit_resource(self.src) - manager.commit_resource(self.dst) + manager.commit_resource(self._src) + manager.commit_resource(self._dst) # Disable rp_filtering # self.src.rp_filter = False @@ -143,36 +127,23 @@ class Link(Channel): # Resource lifecycle #-------------------------------------------------------------------------- - @async_task - async def __get__(self): - manager = self._state.manager + def __get__(self): + return (self._src.__get__() | self._dst.__get__()) > async_task(self._commit)() - try: - await run_task(self.src.__get__(), manager) - await run_task(self.dst.__get__(), manager) - except ResourceNotFound: - # This is raised if any of the two side of the VethPair is missing - raise ResourceNotFound - - # We always need to commit the two endpoints so that their attributes - # are correctly updated - await self._commit() - def __create__(self): assert self.src_node.get_type() == 'lxccontainer' assert self.dst_node.get_type() == 'lxccontainer' src_host = self.src_node.node dst_host = self.dst_node.node - assert src_host == dst_host host = src_host # Sometimes a down interface persists on one side delif_src = BashTask(self.src_node, CMD_DELETE_IF_EXISTS, - {'interface': self.src}) + {'interface': self._src}) delif_dst = BashTask(self.dst_node, CMD_DELETE_IF_EXISTS, - {'interface': self.dst}) + {'interface': self._dst}) pid_src = get_attributes_task(self.src_node, ['pid']) pid_dst = get_attributes_task(self.dst_node, ['pid']) @@ -185,17 +156,13 @@ class Link(Channel): create = BashTask(host, CMD_CREATE, {'interface': self, 'tmp_src': tmp_src, 'tmp_dst': tmp_dst}) - up_src = BashTask(self.src_node, CMD_UP, {'interface': self.src}) - up_dst = BashTask(self.dst_node, CMD_UP, {'interface': self.dst}) - - @async_task - async def set_state(): - # We always need to commit the two endpoints so that their attributes - # are correctly updated - await self._commit() + up_src = BashTask(self.src_node, CMD_UP, {'interface': self._src}) + up_dst = BashTask(self.dst_node, CMD_UP, {'interface': self._dst}) delif = delif_src | delif_dst up = up_src | up_dst pid = pid_src | pid_dst - return ((delif > (pid @ create)) > up) > set_state() + return ((delif > (pid @ create)) > up) > async_task(self._commit)() + def __delete__(self): + return self._src.__delete__() | self._dst.__delete__() diff --git a/vicn/resource/linux/net_device.py b/vicn/resource/linux/net_device.py index f0a08991..84a946a4 100644 --- a/vicn/resource/linux/net_device.py +++ b/vicn/resource/linux/net_device.py @@ -464,6 +464,9 @@ class NonTapBaseNetDevice(BaseNetDevice): # Attributes #-------------------------------------------------------------------------- + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + def _get_offload(self): return BashTask(self.node, CMD_GET_OFFLOAD, {'netdevice': self}, parse = lambda rv : rv.stdout.strip() == 'on') diff --git a/vicn/resource/linux/physical.py b/vicn/resource/linux/physical.py index e5eba2d3..8decb517 100644 --- a/vicn/resource/linux/physical.py +++ b/vicn/resource/linux/physical.py @@ -22,16 +22,17 @@ import logging import subprocess import shlex -from netmodel.model.type import String, Integer -from netmodel.util.misc import is_local_host -from netmodel.util.socket import check_port -from vicn.core.attribute import Attribute -from vicn.core.commands import Command, ReturnValue -from vicn.core.exception import ResourceNotFound -from vicn.core.task import Task, task -from vicn.resource.node import Node, DEFAULT_USERNAME -from vicn.resource.node import DEFAULT_SSH_PUBLIC_KEY -from vicn.resource.node import DEFAULT_SSH_PRIVATE_KEY +from netmodel.model.type import String, Integer +from netmodel.util.misc import is_local_host +from netmodel.util.socket import check_port +from vicn.core.attribute import Attribute +from vicn.core.commands import Command, ReturnValue +from vicn.core.exception import ResourceNotFound, VICNException +from vicn.core.task import Task, task +from vicn.resource.linux.keypair import Keypair +from vicn.resource.node import Node, DEFAULT_USERNAME +from vicn.resource.node import DEFAULT_SSH_PUBLIC_KEY +from vicn.resource.node import DEFAULT_SSH_PRIVATE_KEY log = logging.getLogger(__name__) @@ -42,6 +43,9 @@ CMD_SSH = 'ssh {ssh_options} -i {private_key} -p {port} ' \ CMD_SSH_NF = 'ssh -n -f {ssh_options} -i {private_key} -p {port} ' \ '{user}@{host} {command}' +FN_KEY = os.path.expanduser(os.path.join( + '~', '.vicn', 'ssh_client_cert', 'ssh_client_key')) + class Physical(Node): """ Resource: Physical @@ -67,12 +71,20 @@ class Physical(Node): # Resource lifecycle #-------------------------------------------------------------------------- - @task - def __get__(self, attributes=None): + def __subresources__(self): + """ + Require a SSH keypair to be present for authentication on nodes + """ + return Keypair(node = None, key = FN_KEY) + + def __initialize__(self): + """ + Initialization require the ssh port to be open on the node, and the ssh + public key to be copied on the remote node. + """ if not check_port(self.hostname, self.ssh_port): - raise ResourceNotFound + raise VICNException - def __create__(self): tasks = list() modes = (True, False) if DEFAULT_USERNAME != 'root' else (True,) for as_root in modes: diff --git a/vicn/resource/lxd/lxd_hypervisor.py b/vicn/resource/lxd/lxd_hypervisor.py index 328f3fdf..b6e1c9ff 100644 --- a/vicn/resource/lxd/lxd_hypervisor.py +++ b/vicn/resource/lxd/lxd_hypervisor.py @@ -44,11 +44,10 @@ logging.getLogger("requests").setLevel(logging.WARNING) logging.getLogger("urllib3").setLevel(logging.WARNING) log = logging.getLogger(__name__) -# FIXME use system-wide files -DEFAULT_CERT_PATH = os.path.join(os.path.dirname(__file__), - '..', '..', '..', 'config', 'lxd_client_cert', 'client_cert.pem') -DEFAULT_KEY_PATH = os.path.join(os.path.dirname(__file__), - '..', '..', '..', 'config', 'lxd_client_cert', 'client_key.pem') +DEFAULT_CERT_PATH = os.path.expanduser(os.path.join( + '~', '.vicn', 'lxd_client_cert', 'client_cert.pem')) +DEFAULT_KEY_PATH = os.path.expanduser(os.path.join( + '~', '.vicn', 'lxd_client_cert', 'client_key.pem')) # FIXME hardcoded password for LXD server DEFAULT_TRUST_PASSWORD = 'vicn' @@ -191,8 +190,7 @@ class LxdHypervisor(Service): cert = DEFAULT_CERT_PATH, key = DEFAULT_KEY_PATH, owner = self) - lxd_cert_install = LxdInstallCert(node = Reference(self, 'node'), - certificate = lxd_local_cert, + lxd_cert_install = LxdInstallCert(certificate = lxd_local_cert, owner = self) return (lxd_init | lxd_local_cert) > lxd_cert_install diff --git a/vicn/resource/node.py b/vicn/resource/node.py index bfb2f9ec..ad519666 100644 --- a/vicn/resource/node.py +++ b/vicn/resource/node.py @@ -27,10 +27,10 @@ from vicn.core.resource import Resource log = logging.getLogger(__name__) DEFAULT_USERNAME = 'root' -DEFAULT_SSH_PRIVATE_KEY = os.path.join(os.path.dirname(__file__), - '..', '..', 'config', 'ssh_client_cert', 'ssh_client_key') -DEFAULT_SSH_PUBLIC_KEY = os.path.join(os.path.dirname(__file__), - '..', '..', 'config', 'ssh_client_cert', 'ssh_client_key.pub') +DEFAULT_SSH_PRIVATE_KEY = os.path.expanduser(os.path.join( + '~', '.vicn', 'ssh_client_cert', 'ssh_client_key')) +DEFAULT_SSH_PUBLIC_KEY = os.path.expanduser(os.path.join( + '~', '.vicn', 'ssh_client_cert', 'ssh_client_key.pub')) class Node(Resource): """ diff --git a/vicn/resource/ns3/emulated_channel.py b/vicn/resource/ns3/emulated_channel.py index 08d7a14b..5f61960c 100644 --- a/vicn/resource/ns3/emulated_channel.py +++ b/vicn/resource/ns3/emulated_channel.py @@ -69,7 +69,7 @@ class EmulatedChannel(Channel, Application): ap = Attribute(Node, description = 'AP', key = True) stations = Attribute(Node, description = 'List of stations', multiplicity = Multiplicity.OneToMany, key = True) - control_port = Attribute(Integer, + control_port = Attribute(Integer, description = 'Control port for the simulation') # Overloaded attributes @@ -141,7 +141,7 @@ class EmulatedChannel(Channel, Application): managed = False) self._ap_if = VethPair(node = self.ap, name = 'vh-' + ap.name + '-' + self.name, - device_name = 'vh-' + ap.name + '-' + self.name, + device_name = 'vh-' + ap.name + '-' + self.name, host = host, owner = self) self._ap_bridged = self._ap_if.host @@ -152,7 +152,7 @@ class EmulatedChannel(Channel, Application): interfaces.append(self._ap_if) # Add a tap interface for the AP... - self._ap_tap = TapDevice(node = self.node, + self._ap_tap = TapDevice(node = self.node, owner = self, device_name = 'tap-' + ap.name + '-' + self.name, up = True, @@ -165,11 +165,11 @@ class EmulatedChannel(Channel, Application): await wait_resources(interfaces) # NOTE: only set channel after the resource is created or it might - # create loops which, at this time, are not handled + # create loops which, at this time, are not handled self._ap_if.set('channel', self) # Add interfaces to bridge - vlan = AddressManager().get('vlan', self, tag='ap') + vlan = AddressManager().get('vlan', self, tag='ap') # AS the container has created the VethPair already without Vlan, we # need to delete and recreate it @@ -181,8 +181,6 @@ class EmulatedChannel(Channel, Application): task = self.node.bridge._add_interface(self._ap_tap, vlan = vlan) await run_task(task, self._state.manager) - print('/!\ pass information to the running simulation') - @inline_task def _get_ap(self): return {'ap': None} diff --git a/vicn/resource/ns3/emulated_lte_channel.py b/vicn/resource/ns3/emulated_lte_channel.py index 8c7382cb..39370228 100644 --- a/vicn/resource/ns3/emulated_lte_channel.py +++ b/vicn/resource/ns3/emulated_lte_channel.py @@ -61,7 +61,7 @@ class EmulatedLteChannel(EmulatedChannel): # ... and each station if not station.managed: sta_if = None - else: + else: if isinstance(station, LxcContainer): host = NetDevice(node = station.node, device_name='vhh-' + station.name + '-' + self.name, @@ -103,8 +103,8 @@ class EmulatedLteChannel(EmulatedChannel): task = self.node.bridge._remove_interface(bridged_sta) await run_task(task, self._state.manager) - - task = self.node.bridge._add_interface(bridged_sta, + + task = self.node.bridge._add_interface(bridged_sta, vlan = vlan) await run_task(task, self._state.manager) @@ -178,8 +178,8 @@ class EmulatedLteChannel(EmulatedChannel): # Coma-separated list of stations' IP/netmask len 'sta-ips' : ','.join(sta_ips), # Base station IP/netmask len - 'bs-ip' : AddressManager().get_ip(self._ap_if) + - DEFAULT_NETMASK, + 'bs-ip' : AddressManager().get_ip(self._ap_if) + '/' + + str(DEFAULT_NETMASK), 'txBuffer' : '800000', 'isFading' : 'true' if DEFAULT_FADING_ENABLED else 'false', } |