forked from sampozz/SDN-Slice-Setup-Optimization
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmininet_simulation.py
151 lines (119 loc) · 4.54 KB
/
mininet_simulation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from mininet.node import OVSKernelSwitch, RemoteController
from mininet.cli import CLI
from mininet.link import TCLink
from comnetsemu.net import Containernet, VNFManager, APPContainer
from network.globals import FAT_TREE_K, services, clients
from network.topology import FatTreeTopo
from os import system
import pickle
import pathlib
import time
import typing
mgr: VNFManager = None
running_services: typing.Dict[str, str] = {} # Local list of running services,
# to be compared to the global one save in services.obj
abs_path = pathlib.Path(__file__).parent.resolve()
def migrate_service(name: str, old_ip: str, new_ip: str) -> APPContainer:
""" Move the container running on a host to a new host
@param old_ip: The IP address of the host running the container
@param new_ip: The IP address of the host where to run the new container
"""
old_hostname = get_hostname(old_ip)
new_srv = spawn_service(name, new_ip)
try:
mgr.removeContainer( f'srv{name}_{old_hostname}' )
except:
# Workaround to fix Permission Denied error on container removal
system(f'docker exec -it srv{name}_{old_hostname} kill 1')
mgr.removeContainer( f'srv{name}_{old_hostname}' )
running_services[name] = new_ip
return new_srv
def spawn_service(name: str, ip: str) -> APPContainer:
""" Run a new container as a service inside specified host
@param name: The name of the container
@param ip: The IP Address of the target host
@return The created container object
"""
hostname = get_hostname(ip)
running_services[name] = ip
return mgr.addContainer(
name=f'srv{name}_{hostname}',
dhost=hostname,
dimage='service_migration',
dcmd='python3 /home/server.py ' + ip,
docker_args={
'volumes': {f'{abs_path}/services/' : { 'bind': '/home', 'mode': 'ro' } }
}
)
def spawn_client(name: str, host: str, target_srv: str) -> APPContainer:
""" Run a new container as a client inside specified host
@param name: The name of the container
@param host: The mininet hostname
@param target_srv: The service IP that the client will connect to
@return The created container object
"""
return mgr.addContainer(
name=name,
dhost=host,
dimage='service_migration',
dcmd='python3 /home/client.py ' + target_srv,
docker_args={
'volumes': {f'{abs_path}/services/' : { 'bind': '/home', 'mode': 'ro' } }
}
)
def get_hostname(ip: str) -> str:
""" Get mininet host name given its ip address
@param ip: IP address of the host
@return The host name related to the ip provided
"""
split = ip.split('.')
return f'p{split[1]}_s{split[2]}_h{split[3]}'
def main():
# Dump services dict to make it globally available
global services
with open('./services/services.obj', 'wb') as file:
pickle.dump(services, file)
# Create topology and start network
topo = FatTreeTopo(FAT_TREE_K)
net = Containernet(
topo=topo,
controller = RemoteController("c0", ip="127.0.0.1"),
switch=OVSKernelSwitch,
build=False,
autoSetMacs=True,
autoStaticArp=True,
link=TCLink,
)
global mgr
mgr = VNFManager(net)
net.build()
net.start()
# Spawn clients
for c_name, c_host, target in clients:
spawn_client(name=c_name, host=c_host, target_srv=target)
simulation_running = True
while simulation_running:
try:
# Check if services were updated by scheduler
for srv, ip in services.items():
# Load services
with open('./services/services.obj', 'rb') as file:
services = pickle.load(file)
# Check for updates on services
if srv not in running_services.keys():
# A new service was spawned
spawn_service(srv, ip)
print(f'Created service {srv} on host {ip}')
if running_services[srv] != ip:
# A service must be migrated
migrate_service(srv, running_services[srv], ip)
print(f'Migrated service {srv} to host {ip}')
time.sleep(2)
except EOFError:
print('Cannot access services.obj file')
except KeyboardInterrupt:
simulation_running = False
CLI(net)
net.stop()
if __name__ == "__main__":
main()