Skip to content

Commit 824b222

Browse files
committed
Merge branch 'hash_4_add_hash_keys' of https://github.com/William-zx/sonic-mgmt into hash_4_add_hash_keys
2 parents ff10e73 + 38900a7 commit 824b222

33 files changed

Lines changed: 1612 additions & 339 deletions

ansible/config_sonic_basedon_testbed.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,49 @@
144144
become: true
145145
when: stat_result.stat.exists is defined and stat_result.stat.exists
146146

147+
- name: Init account key and proxy
148+
set_fact:
149+
core_key: ""
150+
core_proxy: ""
151+
152+
- name: read account key
153+
set_fact:
154+
core_key: "{{ corefile_uploader['azure_sonic_core_storage']['account_key'] }}"
155+
when: corefile_uploader['azure_sonic_core_storage']['account_key'] is defined
156+
157+
- name: read https proxy
158+
set_fact:
159+
core_proxy: "{{ corefile_uploader['env']['https_proxy'] }}"
160+
when: corefile_uploader['env']['https_proxy'] is defined
161+
162+
- name: Put secret in core_analyzer.rc.json
163+
lineinfile:
164+
name: /etc/sonic/core_analyzer.rc.json
165+
regexp: '(^.*)account_key'
166+
line: '\1account_key": "{{ core_key }}",'
167+
backrefs: yes
168+
become: true
169+
when: core_key != ""
170+
171+
- name: Put https-proxy in core_analyzer.rc.json
172+
lineinfile:
173+
name: /etc/sonic/core_analyzer.rc.json
174+
regexp: '(^.*)https_proxy'
175+
line: '\1https_proxy": "{{ core_proxy }}"'
176+
backrefs: yes
177+
become: true
178+
when: core_proxy != ""
179+
180+
- name: enable core uploader service
181+
become: true
182+
command: systemctl enable core_uploader.service
183+
when: core_key != ""
184+
185+
- name: start core uploader service
186+
become: true
187+
command: systemctl start core_uploader.service
188+
when: core_key != ""
189+
147190
- name: Replace snmp community string
148191
lineinfile:
149192
name: /etc/sonic/snmp.yml

ansible/doc/README.testbed.cEOS.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# cEOS
2+
3+
This document discusses how to use cEOS as DUT neighbor device.
4+
5+
cEOS is the container-based EOS. All the software running inside
6+
the container. Compared with vEOS, cEOS has much smaller memory
7+
footprint.
8+
9+
Follow [instruction](README.testbed.VsSetup.md) to setup cEOS testbed.
10+
11+
In below example, there are four cEOS containers.
12+
13+
```
14+
lgh@jenkins-worker-15:~$ docker ps
15+
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16+
fe48c207a51c ceosimage:4.23.2F-1 "/sbin/init systemd.…" 8 days ago Up 8 days ceos_vms6-1_VM0103
17+
52297010e66a ceosimage:4.23.2F-1 "/sbin/init systemd.…" 8 days ago Up 8 days ceos_vms6-1_VM0102
18+
8dd95269b312 ceosimage:4.23.2F-1 "/sbin/init systemd.…" 8 days ago Up 8 days ceos_vms6-1_VM0101
19+
3a50dd481bfb ceosimage:4.23.2F-1 "/sbin/init systemd.…" 8 days ago Up 8 days ceos_vms6-1_VM0100
20+
b91b48145def debian:jessie "bash" 8 days ago Up 8 days net_vms6-1_VM0103
21+
d1ff26d84249 debian:jessie "bash" 8 days ago Up 8 days net_vms6-1_VM0102
22+
1489f52b9617 debian:jessie "bash" 8 days ago Up 8 days net_vms6-1_VM0101
23+
ce1214a008ed debian:jessie "bash" 8 days ago Up 8 days net_vms6-1_VM0100
24+
```
25+
26+
## Resource consumption
27+
28+
A cEOS containers consumes around 1G memory.
29+
30+
```
31+
lgh@jenkins-worker-15:~$ docker stats --no-stream
32+
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 6
33+
fe48c207a51c ceos_vms6-1_VM0103 2.04% 970.9MiB / 125.9GiB 0.75% 0B / 0B 365MB / 55.8GB 138
34+
52297010e66a ceos_vms6-1_VM0102 2.19% 965.4MiB / 125.9GiB 0.75% 0B / 0B 237MB / 55.6GB 139
35+
8dd95269b312 ceos_vms6-1_VM0101 1.93% 980.9MiB / 125.9GiB 0.76% 0B / 0B 300MB / 55.9GB 138
36+
3a50dd481bfb ceos_vms6-1_VM0100 2.05% 970.2MiB / 125.9GiB 0.75% 0B / 0B 365MB / 56.1GB 138
37+
```
38+
39+
## Network Setup
40+
41+
We first create a base container `net_${testbed_name}_${vm_name}`, inject six ethernet ports into the base container,
42+
and then start cEOS `ceos_${testbed_name}_${vm_name}` container on top of the base container. The six ethernet ports
43+
are used for
44+
- 1 management port
45+
- 4 front panel ports to DUT
46+
- 1 backplane port to PTF docker
47+
48+
```
49+
+------------+ +----+
50+
| cEOS Ma0 +--------- VM0100-m ---+ br |
51+
| | +----+
52+
| |
53+
| | +--------------+
54+
| Et1 +----------VM0100-t0---+ br-VM0100-0 |
55+
| | +--------------+
56+
| |
57+
| | +--------------+
58+
| Et2 +----------VM0100-t1---+ br-VM0100-1 |
59+
| | +--------------+
60+
| |
61+
| | +--------------+
62+
| Et3 +----------VM0100-t2---+ br-VM0100-2 |
63+
| | +--------------+
64+
| |
65+
| | +--------------+
66+
| Et4 +----------VM0100-t3---+ br-VM0100-3 |
67+
| | +--------------+
68+
| |
69+
| | +--------------+
70+
| Et5 +----------VM0100-back--+ br-b-vms6-1 |
71+
| | +--------------+
72+
+------------+
73+
```
74+
75+
## Configuration
76+
77+
The `/mnt/flash` in cEOS container is mount to `/data/ceos/ceos_${testbed_name}_${vm_name}` on the host. The `/mnt/flash`
78+
contiains the configuration file and logs.
79+
80+
```
81+
lgh@jenkins-worker-15:~$ ls -l /data/ceos/ceos_vms6-1_VM0100/
82+
total 40
83+
-rw-rw-r--+ 1 root root 924 Mar 31 07:35 AsuFastPktTransmit.log
84+
drwxrwxr-x+ 2 root root 4096 Mar 31 03:31 Fossil
85+
-rw-rw-r--+ 1 root root 568 Mar 31 07:35 SsuRestore.log
86+
-rw-rw-r--+ 1 root root 568 Mar 31 07:35 SsuRestoreLegacy.log
87+
drwxr-xr-x+ 4 897 88 4096 Mar 31 07:35 archive
88+
drwxrwx---+ 3 root root 4096 Mar 18 06:12 debug
89+
drwxrwxr-x+ 2 root root 4096 Mar 18 06:12 fastpkttx.backup
90+
-rw-rw-r--+ 1 root root 180 Mar 31 07:35 kickstart-config
91+
drwxrwxr-x+ 3 root root 4096 Apr 8 09:11 persist
92+
-rw-rwxr--+ 1 root root 1915 Mar 18 06:12 startup-config
93+
```
94+
95+
## Login
96+
97+
There are two ways to get into cEOS container
98+
99+
1. docker exec
100+
```
101+
lgh@jenkins-worker-15:~$ docker exec -it ceos_vms6-1_VM0100 Cli
102+
ARISTA01T1>show int status
103+
Port Name Status Vlan Duplex Speed Type Flags Encapsulation
104+
Et1 connected in Po1 full unconf EbraTestPhyPort
105+
Et2 connected 1 full unconf EbraTestPhyPort
106+
Et3 connected 1 full unconf EbraTestPhyPort
107+
Et4 connected 1 full unconf EbraTestPhyPort
108+
Et5 backplane connected routed full unconf EbraTestPhyPort
109+
Ma0 connected routed full 10G 10/100/1000
110+
Po1 connected routed full unconf N/A
111+
112+
ARISTA01T1>
113+
```
114+
115+
2. ssh
116+
```
117+
lgh@jenkins-worker-15:~$ ssh [email protected]
118+
Password:
119+
ARISTA01T1>show int status
120+
Port Name Status Vlan Duplex Speed Type Flags Encapsulation
121+
Et1 connected in Po1 full unconf EbraTestPhyPort
122+
Et2 connected 1 full unconf EbraTestPhyPort
123+
Et3 connected 1 full unconf EbraTestPhyPort
124+
Et4 connected 1 full unconf EbraTestPhyPort
125+
Et5 backplane connected routed full unconf EbraTestPhyPort
126+
Ma0 connected routed full 10G 10/100/1000
127+
Po1 connected routed full unconf N/A
128+
129+
ARISTA01T1>
130+
```
131+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Configure core file storage secret key and https-proxy as required
2+
#
3+
#corefile_uploader:
4+
# azure_sonic_core_storage:
5+
# account_key: "Your Secret"
6+
# env:
7+
# https_proxy: "http://10.10.10.10:8000"

ansible/roles/test/files/ptftests/advanced-reboot.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@
5757
import re
5858
from collections import defaultdict
5959
import json
60-
import paramiko
6160
import Queue
6261
import pickle
6362
from operator import itemgetter
6463
import scapy.all as scapyall
6564
import itertools
65+
from device_connection import DeviceConnection
6666

6767
from arista import Arista
6868
import sad_path as sp
@@ -125,6 +125,7 @@ def __init__(self):
125125
self.test_params = testutils.test_params_get()
126126
self.check_param('verbose', False, required=False)
127127
self.check_param('dut_username', '', required=True)
128+
self.check_param('dut_password', '', required=True)
128129
self.check_param('dut_hostname', '', required=True)
129130
self.check_param('reboot_limit_in_seconds', 30, required=False)
130131
self.check_param('reboot_type', 'fast-reboot', required=False)
@@ -217,6 +218,12 @@ def __init__(self):
217218

218219
self.allow_vlan_flooding = bool(self.test_params['allow_vlan_flooding'])
219220

221+
self.dut_connection = DeviceConnection(
222+
self.test_params['dut_hostname'],
223+
self.test_params['dut_username'],
224+
password=self.test_params['dut_password']
225+
)
226+
220227
return
221228

222229
def read_json(self, name):
@@ -411,7 +418,7 @@ def get_sad_info(self):
411418
def init_sad_oper(self):
412419
if self.sad_oper:
413420
self.log("Preboot/Inboot Operations:")
414-
self.sad_handle = sp.SadTest(self.sad_oper, self.ssh_targets, self.portchannel_ports, self.vm_dut_map, self.test_params, self.dut_ssh, self.vlan_ports)
421+
self.sad_handle = sp.SadTest(self.sad_oper, self.ssh_targets, self.portchannel_ports, self.vm_dut_map, self.test_params, self.vlan_ports)
415422
(self.ssh_targets, self.portchannel_ports, self.neigh_vm, self.vlan_ports), (log_info, fails) = self.sad_handle.setup()
416423
self.populate_fail_info(fails)
417424
for log in log_info:
@@ -480,7 +487,6 @@ def setUp(self):
480487
self.reboot_type = self.test_params['reboot_type']
481488
if self.reboot_type not in ['fast-reboot', 'warm-reboot']:
482489
raise ValueError('Not supported reboot_type %s' % self.reboot_type)
483-
self.dut_ssh = self.test_params['dut_username'] + '@' + self.test_params['dut_hostname']
484490
self.dut_mac = self.test_params['dut_mac']
485491

486492
# get VM info
@@ -509,7 +515,7 @@ def setUp(self):
509515
self.from_server_dst_ports = self.portchannel_ports
510516

511517
self.log("Test params:")
512-
self.log("DUT ssh: %s" % self.dut_ssh)
518+
self.log("DUT ssh: %s@%s" % (self.test_params['dut_username'], self.test_params['dut_hostname']))
513519
self.log("DUT reboot limit in seconds: %s" % self.limit)
514520
self.log("DUT mac address: %s" % self.dut_mac)
515521

@@ -1004,7 +1010,7 @@ def reboot_dut(self):
10041010
time.sleep(self.reboot_delay)
10051011

10061012
self.log("Rebooting remote side")
1007-
stdout, stderr, return_code = self.cmd(["ssh", "-oStrictHostKeyChecking=no", self.dut_ssh, "sudo " + self.reboot_type])
1013+
stdout, stderr, return_code = self.dut_connection.execCommand("sudo " + self.reboot_type)
10081014
if stdout != []:
10091015
self.log("stdout from %s: %s" % (self.reboot_type, str(stdout)))
10101016
if stderr != []:
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import paramiko
2+
import logging
3+
from paramiko.ssh_exception import BadHostKeyException, AuthenticationException, SSHException
4+
5+
logger = logging.getLogger(__name__)
6+
7+
DEFAULT_CMD_EXECUTION_TIMEOUT_SEC = 10
8+
9+
class DeviceConnection:
10+
'''
11+
DeviceConnection uses Paramiko module to connect to devices
12+
13+
Paramiko module uses fallback mechanism where it would first try to use
14+
ssh key and that fails, it will attempt username/password combination
15+
'''
16+
def __init__(self, hostname, username, password=None):
17+
'''
18+
Class constructor
19+
20+
@param hostname: hostname of device to connect to
21+
@param username: username for device connection
22+
@param password: password for device connection
23+
'''
24+
self.hostname = hostname
25+
self.username = username
26+
self.password = password
27+
28+
def execCommand(self, cmd, timeout=DEFAULT_CMD_EXECUTION_TIMEOUT_SEC):
29+
'''
30+
Executes command on remote device
31+
32+
@param cmd: command to be run on remote device
33+
@param timeout: timeout for command run session
34+
@return: stdout, stderr, value
35+
stdout is a list of lines of the remote stdout gathered during command execution
36+
stderr is a list of lines of the remote stderr gathered during command execution
37+
value: 0 if command execution raised no exception
38+
nonzero if exception is raised
39+
'''
40+
client = paramiko.SSHClient()
41+
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
42+
43+
if isinstance(cmd, list):
44+
cmd = ' '.join(cmd)
45+
46+
stdOut = stdErr = []
47+
retValue = 1
48+
try:
49+
client.connect(self.hostname, username=self.username, password=self.password, allow_agent=False)
50+
si, so, se = client.exec_command(cmd, timeout=timeout)
51+
stdOut = so.readlines()
52+
stdErr = se.readlines()
53+
retValue = 0
54+
except SSHException as sshException:
55+
logger.error('SSH Command failed with message: %s' % sshException)
56+
except AuthenticationException as authenticationException:
57+
logger.error('SSH Authentiaction failure with message: %s' % authenticationException)
58+
except BadHostKeyException as badHostKeyException:
59+
logger.error('SSH Authentiaction failure with message: %s' % badHostKeyException)
60+
finally:
61+
client.close()
62+
63+
return stdOut, stdErr, retValue

0 commit comments

Comments
 (0)