diff --git a/ansible/group_vars/sonic/vars b/ansible/group_vars/sonic/vars index 532dcdd1edf..42857dc9f10 100644 --- a/ansible/group_vars/sonic/vars +++ b/ansible/group_vars/sonic/vars @@ -50,4 +50,3 @@ dns_servers: ['10.0.0.5', '10.0.0.6'] # snmp variables snmp_rocommunity: public snmp_location: testlab - diff --git a/ansible/group_vars/sonic_latest/package_versions.yml b/ansible/group_vars/sonic_latest/package_versions.yml index 59fc3ce4683..0db689807eb 100644 --- a/ansible/group_vars/sonic_latest/package_versions.yml +++ b/ansible/group_vars/sonic_latest/package_versions.yml @@ -1,7 +1,6 @@ -linux_image: { name: linux-image-3.16.0-4-amd64 , version: 3.16.7-ckt11-2+acs8u2 } platform_modules_s6000: { name: platform-modules-s6000 , version: "*" } opennsl: { name: opennsl-modules-3.16.0-4-amd64 , version: "6.4.5.B*" } -opennslv2: { name: opennsl-modules-3.16.0-4-amd64 , version: "6.4.10*" } +opennslv2: { name: opennsl-modules-3.16.0-4-amd64 , version: "6.5.5*" } version_sx_kernel: "*" version_mlnxsdk: "*" version_iproute2_mlnx: "1.mlnx*" @@ -10,7 +9,7 @@ version_sonic_cli: "*" image_id_database: docker-database:latest image_id_snmp: docker-snmp:latest -image_id_lldp: docker-lldp-sv2:latest +image_id_lldp: docker-lldp:latest image_id_platform_monitor: docker-platform-monitor:latest image_id_syncd: docker-syncd:latest @@ -21,3 +20,5 @@ image_id_orchagent: docker-orchagent:latest image_id_orchagent_mlnx: docker-orchagent-mlnx:latest image_id_orchagent_cavm: docker-orchagent-cavm:latest image_id_fpm: docker-fpm:latest +image_id_snmp_sv2: docker-snmp-sv2:latest +image_id_lldp_sv2: docker-lldp-sv2:latest diff --git a/ansible/library/format_bgp_facts.py b/ansible/library/format_bgp_facts.py deleted file mode 100644 index 9e4d8160932..00000000000 --- a/ansible/library/format_bgp_facts.py +++ /dev/null @@ -1,221 +0,0 @@ -#!/usr/bin/python - - -DOCUMENTATION = ''' -module: format_bgp_facts -version_added: "2.0" -author: John Arnold (johnar@microsoft.com) -short_description: Format BGP neighbor info from different OSes -description: - - Format BGP neighbor information from FTOS, Arista, Nexus etc. - - Retrieved facts will be inserted into the 'bgp_neighbors' key -''' - -EXAMPLES = ''' -- name: Format BGP neighbor information - format_bgp_facts: bgp_neighbors="{{ result.stdout }}" hw_sku_class="Force10" -''' - -# Example of the source data -''' -BGP neighbor is 10.0.0.61, remote AS 64015, local AS 65100, external link - Description: ARISTA15T0 - BGP version 4, remote router ID 0.0.0.0 - BGP state = Active - Last read 6d13h16m, hold time is 180, keepalive interval is 60 seconds - Message statistics: - Inq depth is 0 - Outq depth is 0 - Sent Rcvd - Opens: 1 1 - Notifications: 0 0 - Updates: 6595 3 - Keepalives: 949 948 - Route Refresh: 0 0 - Capability: 0 0 - Total: 7545 952 - Minimum time between advertisement runs is 30 seconds - - For address family: IPv4 Unicast - Community attribute sent to this neighbor(both) - 0 accepted prefixes - - Connections established 1; dropped 1 - Last reset 6d13h15m, due to -Next connect timer due in 31 seconds -Read thread: off Write thread: off -''' - - -class BgpModule(object): - - - def __init__(self): - self.module = AnsibleModule( - argument_spec=dict( - is_sonic=dict(required=False, default=False, type='bool'), - hw_sku_class=dict(required=True, choices=['Force10', 'Nexus']), - bgp_neighbors_string=dict(required=False), - ), - supports_check_mode=True) - - self.is_sonic = self.module.params['is_sonic'] - self.hw_sku_class = self.module.params['hw_sku_class'] - if self.module.params['bgp_neighbors_string']: self.bgp_neighbors_string = self.module.params['bgp_neighbors_string'] - self.facts = {} - - return - - def run(self): - """ - Main method of the class - """ - - if self.bgp_neighbors_string: - if self.is_sonic: - self.parse_sonic_neighbors() - else: - self.parse_neighbors() - - self.module.exit_json(ansible_facts=self.facts) - - def parse_sonic_neighbors(self): - - regex_ip = re.compile(r'^BGP neighbor is (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') - regex_remote_as = re.compile(r'.*remote AS (\d+)') - regex_local_as = re.compile(r'.*local AS (\d+)') - regex_desc = re.compile(r'.*Description: (.*)') - regex_stats = re.compile(r'.*(Opens|Notifications|Updates|Keepalives|Route Refresh|Capability|Total):.*') - regex_state = re.compile(r'.*BGP state = (\w+)') - regex_mrai = re.compile(r'.*Minimum time between advertisement runs is (\d{1,4})') - regex_accepted = re.compile(r'.*(\d+) accepted prefixes') - regex_conn_est = re.compile(r'.*Connections established (\d+)') - regex_conn_dropped = re.compile(r'.*Connections established \d+; dropped (\d+)') - regex_routerid = re.compile(r'.*remote router ID (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') - - neighbors = {} - - try: - split_output = self.bgp_neighbors_string.split("BGP neighbor") - - for n in split_output: - - # ignore empty rows - if 'BGP' in n: - neighbor = {} - message_stats = {} - n = "BGP neighbor" + n - lines = n.splitlines() - - for line in lines: - if regex_ip.match(line): neighbor_ip = regex_ip.match(line).group(1) - if regex_remote_as.match(line): neighbor['remote AS'] = int(regex_remote_as.match(line).group(1)) - if regex_local_as.match(line): neighbor['local AS'] = int(regex_local_as.match(line).group(1)) - if regex_desc.match(line): neighbor['description'] = regex_desc.match(line).group(1) - if regex_state.match(line): neighbor['state'] = regex_state.match(line).group(1).lower() - if regex_mrai.match(line): neighbor['mrai'] = int(regex_mrai.match(line).group(1)) - if regex_accepted.match(line): neighbor['accepted prefixes'] = int(regex_accepted.match(line).group(1)) - if regex_conn_est.match(line): neighbor['connections established'] = int(regex_conn_est.match(line).group(1)) - if regex_conn_dropped.match(line): neighbor['connections dropped'] = int(regex_conn_dropped.match(line).group(1)) - if regex_routerid.match(line): neighbor['remote routerid'] = regex_routerid.match(line).group(1) - - if regex_stats.match(line): - key, values = line.split(':') - key = key.lstrip() - sent, rcvd = values.split() - value_dict = {} - value_dict['sent'] = int(sent) - value_dict['rcvd'] = int(rcvd) - message_stats[key] = value_dict - - if message_stats: - neighbor['message statistics'] = message_stats - - neighbors[neighbor_ip] = neighbor - - except Exception as e: - self.module.fail_json(msg=str(e)) - - self.facts['bgp_neighbors'] = neighbors - - return - - def parse_neighbors(self): - - - regex_ip = re.compile(r'^BGP neighbor is (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') - regex_remote_as = re.compile(r'.*remote AS (\d+)') - regex_local_as = re.compile(r'.*local AS (\d+)') - if self.hw_sku_class == "Force10": - regex_desc = re.compile(r'.*Description : (.*)') - regex_stats = re.compile(r'.*(Opens|Notifications|Updates|Keepalives|Route Refresh|Capability|Total):.*') - regex_state = re.compile(r'.*BGP state (\w+)') - elif self.hw_sku_class == "Nexus": - regex_desc = re.compile(r'.*Description\s*:\s*(.*)') - regex_stats = re.compile(r'.*(Opens|Notifications|Updates|Keepalives|Route Refresh|Capability|Total):\s+(\d+)\s+(\d+)') - regex_state = re.compile(r'.*BGP state =?\s*(\w+)') - regex_mrai = re.compile(r'.*Minimum time between advertisement runs is (\d{1,4})') - regex_accepted = re.compile(r'.*Prefixes accepted (\d+)') - regex_conn_est = re.compile(r'.*Connections established (\d+)') - regex_conn_dropped = re.compile(r'.*Connections established \d+; dropped (\d+)') - regex_routerid = re.compile(r'.*remote router ID (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') - - neighbors = {} - - try: - split_output = self.bgp_neighbors_string.split("BGP neighbor") - - for n in split_output: - - # ignore empty rows - if 'BGP' in n: - neighbor = {} - message_stats = {} - n = "BGP neighbor" + n - lines = n.splitlines() - - for line in lines: - if regex_ip.match(line): neighbor_ip = regex_ip.match(line).group(1) - if regex_remote_as.match(line): neighbor['remote AS'] = int(regex_remote_as.match(line).group(1)) - if regex_local_as.match(line): neighbor['local AS'] = int(regex_local_as.match(line).group(1)) - if regex_desc.match(line): neighbor['description'] = regex_desc.match(line).group(1) - if regex_state.match(line): neighbor['state'] = regex_state.match(line).group(1).lower() - if regex_mrai.match(line): neighbor['mrai'] = int(regex_mrai.match(line).group(1)) - if regex_accepted.match(line): neighbor['accepted prefixes'] = int(regex_accepted.match(line).group(1)) - if regex_conn_est.match(line): neighbor['connections established'] = int(regex_conn_est.match(line).group(1)) - if regex_conn_dropped.match(line): neighbor['connections dropped'] = int(regex_conn_dropped.match(line).group(1)) - if regex_routerid.match(line): neighbor['remote routerid'] = regex_routerid.match(line).group(1) - - if regex_stats.match(line): - key, values = line.split(':') - key = key.lstrip() - sent, rcvd = values.split() - value_dict = {} - value_dict['sent'] = int(sent) - value_dict['rcvd'] = int(rcvd) - message_stats[key] = value_dict - - if message_stats: - neighbor['message statistics'] = message_stats - - neighbors[neighbor_ip] = neighbor - - except Exception as e: - self.module.fail_json(msg=str(e)) - - self.facts['bgp_neighbors'] = neighbors - - return - - - -def main(): - bgp = BgpModule() - bgp.run() - - return - - -from ansible.module_utils.basic import * -if __name__ == "__main__": - main() diff --git a/ansible/roles/sonic-common/tasks/lldp.yml b/ansible/roles/sonic-common/tasks/lldp.yml index 56eca16ca98..c9d304314fa 100644 --- a/ansible/roles/sonic-common/tasks/lldp.yml +++ b/ansible/roles/sonic-common/tasks/lldp.yml @@ -1,3 +1,16 @@ +- name: Clean up old container + include: sonicdocker.yml + vars: + docker_container: docker-lldp + docker_image: "{{ image_id_lldp }}" + docker_privileged: yes + docker_state: absent + +- name: switch LLDP image based on SONiC version + set_fact: + image_id_lldp: "{{ image_id_lldp_sv2 }}" + when: sonic_version == "v2" + - name: Ensure LLDP container started include: sonicdocker.yml vars: @@ -13,6 +26,20 @@ dest=/etc/default/lldpd notify: - Restart LLDP Daemon + - Restart SNMP Daemon + + - name: Setup LLDPD Daemon Config File + become: true + copy: src="ssw/{{sonic_hwsku}}/etc/lldpd.conf" + dest=/etc/lldpd.conf + notify: + - Restart LLDP Daemon + - Restart SNMP Daemon + # for production hwsku, we need to add lldpd.conf to generate ngs + # interface name in the lldp message we sent + when: sonic_hwsku != 'ACS-S6000' and sonic_hwsku != 'ACS-MSN2700' + # Force handler flush to trigger daemon restarts + - meta: flush_handlers vars: ansible_shell_type: docker diff --git a/ansible/roles/sonic-common/tasks/sonicdocker.yml b/ansible/roles/sonic-common/tasks/sonicdocker.yml index 5756a664f6c..35b9d083764 100644 --- a/ansible/roles/sonic-common/tasks/sonicdocker.yml +++ b/ansible/roles/sonic-common/tasks/sonicdocker.yml @@ -12,8 +12,9 @@ ## | present | | | present | | y | | ## | started | | | present | started | y | | ## | reloaded | y | pulled? | reloaded | restarted if pulled | y | if pulled | +## | | | | | started if not | | | ## | restarted | | | present | restarted | y | | -## | stopped | | y | stopped | | n | | +## | stopped | | y | stopped | stopped | n | | ## | killed | | y | killed | | n | | ## | absent | | y | absent | | n | y | ## +-------------+------+--------------+----------+---------------------+----------------+-------------+ @@ -149,17 +150,26 @@ log_opt: "{{docker_log_opt}}" ## Container service operation -- name: "{{docker_container}} - Post docker - start container service" - become: true - service: name="{{docker_container}}" - state=started - when: docker_state == 'started' - name: "{{docker_container}} - Post docker - restart container service" become: true service: name="{{docker_container}}" state=restarted when: "docker_state == 'restarted' or \ docker_state == 'reloaded' and 'Status: Downloaded newer image' in pull_result.stdout" + +- name: "{{docker_container}} - Post docker - start container service" + become: true + service: name="{{docker_container}}" + state=started + when: "docker_state == 'started' or docker_state == 'reloaded'" + +- name: "{{docker_container}} - Post docker - stop and disable container service" + become: true + service: name="{{docker_container}}" + state=stopped + enabled=no + when: docker_state == 'stopped' + - name: "{{docker_container}} - Post docker - enable container service" become: true service: name="{{docker_container}}" diff --git a/ansible/roles/sonicv2/files/bin/vtysh b/ansible/roles/sonicv2/files/bin/vtysh deleted file mode 100755 index 359101c06c6..00000000000 --- a/ansible/roles/sonicv2/files/bin/vtysh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -docker exec -i bgp vtysh "$@" diff --git a/ansible/roles/sonicv2/files/bin/vtysh b/ansible/roles/sonicv2/files/bin/vtysh new file mode 120000 index 00000000000..d8831a32985 --- /dev/null +++ b/ansible/roles/sonicv2/files/bin/vtysh @@ -0,0 +1 @@ +../../../sonic-common/files/bin/vtysh \ No newline at end of file diff --git a/ansible/roles/sonicv2/files/docker_clean.sh b/ansible/roles/sonicv2/files/docker_clean.sh deleted file mode 100644 index d384b06f5a6..00000000000 --- a/ansible/roles/sonicv2/files/docker_clean.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# Clean up untagged docker images, ie. ':' -docker images -q --filter "dangling=true" | xargs --no-run-if-empty docker rmi - -# Clean up unused docker images, but ignore untagged docker images -# Note: -# if there is no tag or repository for one image, it will shows as 'repository:' -# or ':TAG' or ':' -# docker ps ...: -# list all used image -# docker images ...: -# list all images by tag and by digest -# grep -xvf A B: -# exclude all lines from file B matching any whole line in file A -grep -xvf <(docker ps -a --format {{.Image}}) <(docker images --format '{{.Repository}}:{{.Tag}}\n{{.Repository}}@{{.Digest}}' | grep -v '') | xargs --no-run-if-empty docker rmi diff --git a/ansible/roles/sonicv2/files/docker_clean.sh b/ansible/roles/sonicv2/files/docker_clean.sh new file mode 120000 index 00000000000..b649a0560a6 --- /dev/null +++ b/ansible/roles/sonicv2/files/docker_clean.sh @@ -0,0 +1 @@ +../../sonic-common/files/docker_clean.sh \ No newline at end of file diff --git a/ansible/roles/sonicv2/files/ssw/ACS-MSN2700/alias_map.json b/ansible/roles/sonicv2/files/ssw/ACS-MSN2700/alias_map.json new file mode 100644 index 00000000000..dd1324ae436 --- /dev/null +++ b/ansible/roles/sonicv2/files/ssw/ACS-MSN2700/alias_map.json @@ -0,0 +1,34 @@ +{ + "Ethernet8": "Ethernet8", + "Ethernet0": "Ethernet0", + "Ethernet4": "Ethernet4", + "Ethernet108": "Ethernet108", + "Ethernet100": "Ethernet100", + "Ethernet104": "Ethernet104", + "Ethernet96": "Ethernet96", + "Ethernet124": "Ethernet124", + "Ethernet120": "Ethernet120", + "Ethernet92": "Ethernet92", + "Ethernet28": "Ethernet28", + "Ethernet52": "Ethernet52", + "Ethernet56": "Ethernet56", + "Ethernet76": "Ethernet76", + "Ethernet72": "Ethernet72", + "Ethernet32": "Ethernet32", + "Ethernet16": "Ethernet16", + "Ethernet36": "Ethernet36", + "Ethernet12": "Ethernet12", + "Ethernet88": "Ethernet88", + "Ethernet24": "Ethernet24", + "Ethernet116": "Ethernet116", + "Ethernet80": "Ethernet80", + "Ethernet112": "Ethernet112", + "Ethernet84": "Ethernet84", + "Ethernet48": "Ethernet48", + "Ethernet44": "Ethernet44", + "Ethernet40": "Ethernet40", + "Ethernet64": "Ethernet64", + "Ethernet60": "Ethernet60", + "Ethernet20": "Ethernet20", + "Ethernet68": "Ethernet68" +} \ No newline at end of file diff --git a/ansible/roles/sonicv2/files/ssw/ACS-S6000/alias_map.json b/ansible/roles/sonicv2/files/ssw/ACS-S6000/alias_map.json new file mode 100644 index 00000000000..b58d147f70c --- /dev/null +++ b/ansible/roles/sonicv2/files/ssw/ACS-S6000/alias_map.json @@ -0,0 +1,34 @@ +{ + "Ethernet8": "fortyGigE0/8", + "Ethernet0": "fortyGigE0/0", + "Ethernet4": "fortyGigE0/4", + "Ethernet108": "fortyGigE0/108", + "Ethernet100": "fortyGigE0/100", + "Ethernet104": "fortyGigE0/104", + "Ethernet96": "fortyGigE0/96", + "Ethernet124": "fortyGigE0/124", + "Ethernet120": "fortyGigE0/120", + "Ethernet92": "fortyGigE0/92", + "Ethernet28": "fortyGigE0/28", + "Ethernet52": "fortyGigE0/52", + "Ethernet56": "fortyGigE0/56", + "Ethernet76": "fortyGigE0/76", + "Ethernet72": "fortyGigE0/72", + "Ethernet32": "fortyGigE0/32", + "Ethernet16": "fortyGigE0/16", + "Ethernet36": "fortyGigE0/36", + "Ethernet12": "fortyGigE0/12", + "Ethernet88": "fortyGigE0/88", + "Ethernet24": "fortyGigE0/24", + "Ethernet116": "fortyGigE0/116", + "Ethernet80": "fortyGigE0/80", + "Ethernet112": "fortyGigE0/112", + "Ethernet84": "fortyGigE0/84", + "Ethernet48": "fortyGigE0/48", + "Ethernet44": "fortyGigE0/44", + "Ethernet40": "fortyGigE0/40", + "Ethernet64": "fortyGigE0/64", + "Ethernet60": "fortyGigE0/60", + "Ethernet20": "fortyGigE0/20", + "Ethernet68": "fortyGigE0/68" +} \ No newline at end of file diff --git a/ansible/roles/sonicv2/files/ssw/Arista-7050-QX32/alias_map.json b/ansible/roles/sonicv2/files/ssw/Arista-7050-QX32/alias_map.json new file mode 100644 index 00000000000..90b35011e2c --- /dev/null +++ b/ansible/roles/sonicv2/files/ssw/Arista-7050-QX32/alias_map.json @@ -0,0 +1,34 @@ +{ + "Ethernet8": "Ethernet3/1", + "Ethernet0": "Ethernet1/1", + "Ethernet4": "Ethernet2/1", + "Ethernet108": "Ethernet28", + "Ethernet100": "Ethernet26", + "Ethernet104": "Ethernet27", + "Ethernet96": "Ethernet25", + "Ethernet124": "Ethernet32", + "Ethernet120": "Ethernet31", + "Ethernet92": "Ethernet24/1", + "Ethernet28": "Ethernet8/1", + "Ethernet52": "Ethernet14/1", + "Ethernet56": "Ethernet15/1", + "Ethernet76": "Ethernet20/1", + "Ethernet72": "Ethernet19/1", + "Ethernet32": "Ethernet9/1", + "Ethernet16": "Ethernet5/1", + "Ethernet36": "Ethernet10/1", + "Ethernet12": "Ethernet4/1", + "Ethernet88": "Ethernet23/1", + "Ethernet24": "Ethernet7/1", + "Ethernet116": "Ethernet30", + "Ethernet80": "Ethernet21/1", + "Ethernet112": "Ethernet29", + "Ethernet84": "Ethernet22/1", + "Ethernet48": "Ethernet13/1", + "Ethernet44": "Ethernet12/1", + "Ethernet40": "Ethernet11/1", + "Ethernet64": "Ethernet17/1", + "Ethernet60": "Ethernet16/1", + "Ethernet20": "Ethernet6/1", + "Ethernet68": "Ethernet18/1" +} \ No newline at end of file diff --git a/ansible/roles/sonicv2/files/ssw/Arista-7050-QX32/port_config.ini b/ansible/roles/sonicv2/files/ssw/Arista-7050-QX32/port_config.ini new file mode 100644 index 00000000000..ec12639d72b --- /dev/null +++ b/ansible/roles/sonicv2/files/ssw/Arista-7050-QX32/port_config.ini @@ -0,0 +1,33 @@ +# alias lanes +Ethernet0 125,126,127,128 +Ethernet4 121,122,123,124 +Ethernet8 13,14,15,16 +Ethernet12 9,10,11,12 +Ethernet16 17,18,19,20 +Ethernet20 21,22,23,24 +Ethernet24 25,26,27,28 +Ethernet28 29,30,31,32 +Ethernet32 37,38,39,40 +Ethernet36 33,34,35,36 +Ethernet40 45,46,47,48 +Ethernet44 41,42,43,44 +Ethernet48 53,54,55,56 +Ethernet52 49,50,51,52 +Ethernet56 69,70,71,72 +Ethernet60 65,66,67,68 +Ethernet64 77,78,79,80 +Ethernet68 73,74,75,76 +Ethernet72 93,94,95,96 +Ethernet76 89,90,91,92 +Ethernet80 101,102,103,104 +Ethernet84 97,98,99,100 +Ethernet88 109,110,111,112 +Ethernet92 105,106,107,108 +Ethernet96 61,62,63,64 +Ethernet100 57,58,59,60 +Ethernet104 81,82,83,84 +Ethernet108 85,86,87,88 +Ethernet112 117,118,119,120 +Ethernet116 113,114,115,116 +Ethernet120 5,6,7,8 +Ethernet124 1,2,3,4 diff --git a/ansible/roles/sonicv2/tasks/sonicdocker.yml b/ansible/roles/sonicv2/tasks/sonicdocker.yml deleted file mode 100644 index 0367a138e2e..00000000000 --- a/ansible/roles/sonicv2/tasks/sonicdocker.yml +++ /dev/null @@ -1,180 +0,0 @@ -## -## Encapsulate docker module with private docker registry, manage the container service -## by systemd on host, so it has full featured depdency control and restart policy -## -## The encapsulated module - sonicdocker -## docker_state: emulate the behavior of docker module -## ref: http://docs.ansible.com/ansible/docker_module.html -## -## +-------------+------+--------------+----------+---------------------+----------------+-------------+ -## | sonicdocker | pull | stop service | docker | post service | enable service | clean image | -## +-------------+------+--------------+----------+---------------------+----------------+-------------+ -## | present | | | present | | y | | -## | started | | | present | started | y | | -## | reloaded | y | pulled? | reloaded | restarted if pulled | y | if pulled | -## | restarted | | | present | restarted | y | | -## | stopped | | y | stopped | | n | | -## | killed | | y | killed | | n | | -## | absent | | y | absent | | n | y | -## +-------------+------+--------------+----------+---------------------+----------------+-------------+ -## - -## Set default values for the module variables, emulating local variable definition -## Note: must be consistent with tail part -- name: "{{docker_container}} - Set docker variable - docker_net" - set_fact: - docker_net: host - when: docker_net is undefined -- name: "{{docker_container}} - Set docker variable - docker_state" - set_fact: - docker_state: reloaded - when: docker_state is undefined -- name: "{{docker_container}} - Set docker variable - docker_volumes" - set_fact: - docker_volumes: [] - when: docker_volumes is undefined -- name: "{{docker_container}} - Set docker variable - docker_privileged" - set_fact: - docker_privileged: no - when: docker_privileged is undefined -- name: "{{docker_container}} - Set docker variable - docker_log_driver" - set_fact: - docker_log_driver: json-file - when: docker_log_driver is undefined -- name: "{{docker_container}} - Set docker variable - docker_env" - set_fact: - docker_env: {} - when: docker_env is undefined -- name: "{{docker_container}} - Set docker variable - docker_tty" - set_fact: - docker_tty: yes - when: docker_tty is undefined -- name: "{{docker_container}} - Set docker variable - docker_log_opt" - set_fact: - docker_log_opt: {} - when: docker_log_driver != "syslog" -- name: "{{docker_container}} - Set docker variable - docker_log_opt" - set_fact: - docker_log_opt: - ## TRICK! TRICK! TRICK! - ## in ansible 2.0.0.2, reference set_fact varialbe will introduce recursive templating - ## so double escape by {{'...'}} and {%raw%}...{%endraw%} - tag: "{{'{%raw%}{{.ID}}({{.Name}}{%endraw%}'}})" - when: docker_log_driver == "syslog" - -## Local variables -- name: "{{docker_container}} - Set docker variable - sonicdocker_container_state" - set_fact: - sonicdocker_container_state: "{{docker_state}}" -- name: "{{docker_container}} - Set docker variable - sonicdocker_container_state" - set_fact: - sonicdocker_container_state: present - when: docker_state in ['present', 'started', 'restarted'] - -## Copy systemd config files for docker container -- name: "{{docker_container}} - Copy systemd config files for docker container" - become: true - template: - src="etc/systemd/system/{{docker_container}}.j2" - dest="/etc/systemd/system/{{docker_container}}.service" - owner=root - group=root - mode=0644 - register: configfile_result - when: "docker_state not in ['absent']" - -- name: "{{docker_container}} - Reload systemd" - command: systemctl daemon-reload - become: yes - when: configfile_result.changed - -- block: - ## Clean up images before pulling - - name: "{{docker_container}} - Clean up images before pulling" - include: sonicdocker_clean.yml - - ## Pull docker image from registry - - name: "{{docker_container}} - Pull docker image from registry" - shell: docker login -u {{docker_registry_username}} -p {{docker_registry_password}} -e "@" {{docker_registry_host}}; docker pull {{docker_registry_host}}/{{docker_image}} - register: pull_result - changed_when: "'Status: Downloaded newer image' in pull_result.stdout" - when: docker_state == 'reloaded' - -## Stop container service after pulled -- name: "{{docker_container}} - Stop container service after pulled" - become: true - service: name="{{docker_container}}" - state=stopped - when: "(docker_state == 'reloaded' and 'Status: Downloaded newer image' in pull_result.stdout) \ - or docker_state in ['stopped', 'killed']" - -## Clean up systemd config files for docker container -- name: "{{docker_container}} - Delete systemd config file for docker container" - become: true - file: - path="/etc/systemd/system/{{docker_container}}.service" - state=absent - when: "docker_state in ['absent']" - register: configfile_remove - -- name: "{{docker_container}} - Reload systemd" - command: systemctl daemon-reload - become: yes - when: configfile_remove.changed - -- name: "{{docker_container}} - Control docker container" - docker: - name: "{{docker_container}}" - image: "{{docker_registry_host}}/{{docker_image}}" - state: "{{sonicdocker_container_state}}" - ## Already pulled by upper task - pull: missing - detach: yes - net: "{{docker_net}}" - tty: "{{docker_tty}}" - stdin_open: yes - registry: "https://{{docker_registry_host}}" - username: "{{docker_registry_username}}" - password: "{{docker_registry_password}}" - email: "@" - volumes: "{{docker_volumes}}" - privileged: "{{docker_privileged}}" - env: "{{docker_env}}" - log_driver: "{{docker_log_driver}}" - log_opt: "{{docker_log_opt}}" - -## Container service operation -- name: "{{docker_container}} - Post docker - start container service" - become: true - service: name="{{docker_container}}" - state=started - when: docker_state == 'started' -- name: "{{docker_container}} - Post docker - restart container service" - become: true - service: name="{{docker_container}}" - state=restarted - when: "docker_state == 'restarted' or \ - docker_state == 'reloaded' and 'Status: Downloaded newer image' in pull_result.stdout" -- name: "{{docker_container}} - Post docker - enable container service" - become: true - service: name="{{docker_container}}" - enabled={{docker_state in ['present', 'started', 'reloaded', 'restarted']}} - -## Clean up images after pulled and running -- name: "{{docker_container}} - Clean up images after pulled and running" - include: sonicdocker_clean.yml - when: "(docker_state == 'reloaded' and 'Status: Downloaded newer image' in pull_result.stdout) or \ - docker_state == 'absent'" - -## Reset the module variables to default values to prevent global side-effect -## Note: must be consistent with header part -- name: "{{docker_container}} - Clean up sonicdocker variables" - set_fact: - docker_image: '' - docker_net: host - docker_state: reloaded - docker_volumes: [] - docker_privileged: no - docker_log_driver: json-file - docker_env: {} - docker_tty: yes diff --git a/ansible/roles/sonicv2/tasks/sonicdocker.yml b/ansible/roles/sonicv2/tasks/sonicdocker.yml new file mode 120000 index 00000000000..a213a224cfa --- /dev/null +++ b/ansible/roles/sonicv2/tasks/sonicdocker.yml @@ -0,0 +1 @@ +../../sonic-common/tasks/sonicdocker.yml \ No newline at end of file diff --git a/ansible/roles/sonicv2/tasks/sonicdocker_clean.yml b/ansible/roles/sonicv2/tasks/sonicdocker_clean.yml deleted file mode 100644 index 05632a38b24..00000000000 --- a/ansible/roles/sonicv2/tasks/sonicdocker_clean.yml +++ /dev/null @@ -1,5 +0,0 @@ -- name: Clean up unused docker images - script: "files/docker_clean.sh" - register: rmi_result - changed_when: rmi_result.stdout != "" - failed_when: rmi_result.stderr != "" or rmi_result.rc != 0 diff --git a/ansible/roles/sonicv2/tasks/sonicdocker_clean.yml b/ansible/roles/sonicv2/tasks/sonicdocker_clean.yml new file mode 120000 index 00000000000..f0e8c352d3c --- /dev/null +++ b/ansible/roles/sonicv2/tasks/sonicdocker_clean.yml @@ -0,0 +1 @@ +../../sonic-common/tasks/sonicdocker_clean.yml \ No newline at end of file diff --git a/ansible/roles/test/files/docker_clean.sh b/ansible/roles/test/files/docker_clean.sh new file mode 120000 index 00000000000..b649a0560a6 --- /dev/null +++ b/ansible/roles/test/files/docker_clean.sh @@ -0,0 +1 @@ +../../sonic-common/files/docker_clean.sh \ No newline at end of file diff --git a/ansible/roles/test/files/saitests/copp_tests.py b/ansible/roles/test/files/saitests/copp_tests.py index b45fe188298..21f2062f90a 100644 --- a/ansible/roles/test/files/saitests/copp_tests.py +++ b/ansible/roles/test/files/saitests/copp_tests.py @@ -1,4 +1,4 @@ -# ptf --test-dir saitests copp_tests --qlen=10000 --platform nn -t "verbose=True;dst_mac='00:02:03:04:05:00'" --device-socket 0-3@tcp://127.0.0.1:10900 --device-socket 1-3@tcp://10.3.147.47:10900 +# ptf --test-dir saitests copp_tests --qlen=100000 --platform nn -t "verbose=True" --device-socket 0-3@tcp://127.0.0.1:10900 --device-socket 1-3@tcp://10.3.147.47:10900 # # copp_test.${name_test} # @@ -28,19 +28,13 @@ class ControlPlaneBaseTest(BaseTest): PPS_LIMIT_MIN = PPS_LIMIT * 0.9 PPS_LIMIT_MAX = PPS_LIMIT * 1.1 NO_POLICER_LIMIT = PPS_LIMIT * 1.4 - PKT_TX_COUNT = 5000 + PKT_TX_COUNT = 100000 PKT_RX_LIMIT = PKT_TX_COUNT * 0.90 def __init__(self): BaseTest.__init__(self) - self.test_params = testutils.test_params_get() - - self.mac_map = [] - for i in xrange(self.MAX_PORTS): - output = ControlPlaneBaseTest.cmd_run('ip link show dev eth%d' % (i)) - second = output.split('\n')[1] - mac = second.split()[1] - self.mac_map.append(mac) + test_params = testutils.test_params_get() + self.verbose = 'verbose' in test_params and test_params['verbose'] self.myip = {} self.peerip = {} @@ -50,20 +44,19 @@ def __init__(self): return - @staticmethod - def cmd_run(cmdline): - cmd = cmdline.split(' ') - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = process.communicate() - ret_code = process.returncode - - if ret_code != 0: - raise Exception("ret_code=%d, error message=%s. cmd=%s" % (ret_code, stderr, cmdline)) - - return stdout - def setUp(self): self.dataplane = ptf.dataplane_instance + + self.my_mac = {} + self.peer_mac = {} + for port_id, port in self.dataplane.ports.iteritems(): + if port_id[0] == 0: + self.my_mac[port_id[1]] = port.mac() + elif port_id[0] == 1: + self.peer_mac[port_id[1]] = port.mac() + else: + assert True + self.dataplane.flush() if config["log_dir"] != None: filename = os.path.join(config["log_dir"], str(self)) + ".pcap" @@ -74,6 +67,12 @@ def tearDown(self): self.dataplane.stop_pcap() def copp_test(self, packet, count, send_intf, recv_intf): + if self.verbose: + b_c_0 = self.dataplane.get_counters(*send_intf) + b_c_1 = self.dataplane.get_counters(*recv_intf) + b_n_0 = self.dataplane.get_nn_counters(*send_intf) + b_n_1 = self.dataplane.get_nn_counters(*recv_intf) + start_time=datetime.datetime.now() for i in xrange(count): @@ -81,14 +80,31 @@ def copp_test(self, packet, count, send_intf, recv_intf): end_time=datetime.datetime.now() - total_rcv_pkt_cnt = 0 - while True: - (rcv_device, rcv_port, rcv_pkt, pkt_time) = dp_poll(self, device_number=recv_intf[0], port_number=recv_intf[1], timeout=1) - if rcv_pkt is not None: - if match_exp_pkt(packet, rcv_pkt): - total_rcv_pkt_cnt += 1 - else: - break + total_rcv_pkt_cnt = testutils.count_matched_packets(self, packet, recv_intf[1], recv_intf[0]) + + if self.verbose: + e_c_0 = self.dataplane.get_counters(*send_intf) + e_c_1 = self.dataplane.get_counters(*recv_intf) + e_n_0 = self.dataplane.get_nn_counters(*send_intf) + e_n_1 = self.dataplane.get_nn_counters(*recv_intf) + print + print + print "Counters before the test:" + print "If counter (0, n): ", b_c_0 + print "NN counter (0, n): ", b_n_0 + print "If counter (1, n): ", b_c_1 + print "NN counter (1, n): ", b_n_1 + print + print "Counters after the test:" + print "If counter (0, n): ", e_c_0 + print "NN counter (0, n): ", e_n_0 + print "If counter (1, n): ", e_c_1 + print "NN counter (1, n): ", e_n_1 + print + print "Sent through NN to local ptf_nn_agent: ", e_c_0[1] - b_c_0[1] + print "Sent through If to remote ptf_nn_agent: ", e_n_0[1] - b_n_0[1] + print "Recv from If on remote ptf_nn_agent: ", e_c_1[0] - b_c_1[0] + print "Recv from NN on from remote ptf_nn_agent: ", e_n_1[0] - b_n_1[0] time_delta = end_time - start_time time_delta_ms = (time_delta.microseconds + time_delta.seconds * 10**6) / 10**3 @@ -105,7 +121,7 @@ def check_constraints(self, total_rcv_pkt_cnt, time_delta_ms, rx_pps): def one_port_test(self, port_number): packet = self.contruct_packet(port_number) - total_rcv_pkt_cnt, time_delta, time_delta_ms, tx_pps, rx_pps = self.copp_test(packet, self.PKT_TX_COUNT, (0, port_number), (1, port_number)) + total_rcv_pkt_cnt, time_delta, time_delta_ms, tx_pps, rx_pps = self.copp_test(str(packet), self.PKT_TX_COUNT, (0, port_number), (1, port_number)) self.printStats(self.PKT_TX_COUNT, total_rcv_pkt_cnt, time_delta, tx_pps, rx_pps) self.check_constraints(total_rcv_pkt_cnt, time_delta_ms, rx_pps) @@ -115,8 +131,9 @@ def run_suite(self): self.one_port_test(3) def printStats(self, pkt_send_count, total_rcv_pkt_cnt, time_delta, tx_pps, rx_pps): - if not(('verbose' in self.test_params) and (self.test_params['verbose'] == True)): + if not self.verbose: return + print print 'test stats' print 'Packet sent = %10d' % pkt_send_count print 'Packet rcvd = %10d' % total_rcv_pkt_cnt @@ -140,7 +157,6 @@ def __init__(self): def check_constraints(self, total_rcv_pkt_cnt, time_delta_ms, rx_pps): assert(self.PPS_LIMIT_MIN <= rx_pps <= self.PPS_LIMIT_MAX) - expected_packets = rx_pps*time_delta_ms/1000 # SONIC config contains policer CIR=600 for ARP @@ -152,7 +168,7 @@ def runTest(self): self.run_suite() def contruct_packet(self, port_number): - src_mac = self.mac_map[port_number] + src_mac = self.my_mac[port_number] src_ip = self.myip[port_number] dst_ip = self.peerip[port_number] @@ -176,7 +192,7 @@ def runTest(self): self.run_suite() def contruct_packet(self, port_number): - src_mac = self.mac_map[port_number] + src_mac = self.my_mac[port_number] packet = simple_udp_packet(pktlen=100, eth_dst='ff:ff:ff:ff:ff:ff', eth_src=src_mac, @@ -207,7 +223,7 @@ def runTest(self): self.run_suite() def contruct_packet(self, port_number): - src_mac = self.mac_map[port_number] + src_mac = self.my_mac[port_number] packet = simple_eth_packet( eth_dst='01:80:c2:00:00:0e', eth_src=src_mac, @@ -225,7 +241,7 @@ def runTest(self): self.run_suite() def contruct_packet(self, port_number): - dst_mac = self.test_params['dst_mac'] + dst_mac = self.peer_mac[port_number] dst_ip = self.peerip[port_number] packet = simple_tcp_packet( eth_dst=dst_mac, @@ -261,8 +277,8 @@ def runTest(self): self.run_suite() def contruct_packet(self, port_number): - src_mac = self.mac_map[port_number] - dst_mac = self.test_params['dst_mac'] + src_mac = self.my_mac[port_number] + dst_mac = self.peer_mac[port_number] dst_ip = self.peerip[port_number] packet = simple_udp_packet( eth_dst=dst_mac, @@ -281,7 +297,7 @@ def runTest(self): self.run_suite() def contruct_packet(self, port_number): - dst_mac = self.test_params['dst_mac'] + dst_mac = self.peer_mac[port_number] src_ip = self.myip[port_number] dst_ip = self.peerip[port_number] @@ -303,17 +319,19 @@ def runTest(self): self.run_suite() def one_port_test(self, port_number): - for i in xrange(self.MAX_PORTS): - packet = self.contruct_packet(i) - total_rcv_pkt_cnt, time_delta, time_delta_ms, tx_pps, rx_pps = self.copp_test(packet, self.PKT_TX_COUNT, (0, port_number), (1, port_number)) + for port in self.dataplane.ports.iterkeys(): + if port[0] == 0: + continue + packet = self.contruct_packet(port[1]) + total_rcv_pkt_cnt, time_delta, time_delta_ms, tx_pps, rx_pps = self.copp_test(str(packet), self.PKT_TX_COUNT, (0, port_number), (1, port_number)) self.printStats(self.PKT_TX_COUNT, total_rcv_pkt_cnt, time_delta, tx_pps, rx_pps) self.check_constraints(total_rcv_pkt_cnt, time_delta_ms, rx_pps) return def contruct_packet(self, port_number): - src_mac = self.mac_map[port_number] - dst_mac = self.test_params['dst_mac'] + src_mac = self.my_mac[port_number] + dst_mac = self.peer_mac[port_number] dst_ip = self.peerip[port_number] packet = simple_tcp_packet( @@ -333,7 +351,7 @@ def runTest(self): self.run_suite() def contruct_packet(self, port_number): - dst_mac = self.test_params['dst_mac'] + dst_mac = self.peer_mac[port_number] src_ip = self.myip[port_number] dst_port_number = (port_number + 1) % self.MAX_PORTS dst_ip = self.peerip[dst_port_number] diff --git a/ansible/roles/test/tasks/copp.yml b/ansible/roles/test/tasks/copp.yml index 50294b305ff..83af3b8fdd1 100644 --- a/ansible/roles/test/tasks/copp.yml +++ b/ansible/roles/test/tasks/copp.yml @@ -2,6 +2,16 @@ - fail: msg="Please set ptf_host variable" when: ptf_host is not defined + - name: Ensure LLDP Daemon stopped + become: yes + supervisorctl: state=stopped name={{ item }} + vars: + ansible_shell_type: docker + ansible_python_interpreter: docker exec -i lldp python + with_items: + - lldp-syncd + - lldpd + - name: Disable Mellanox copp rate limiting script: roles/test/files/mlnx/disable_copp_rate_limiting.sh when: minigraph_hwsku is defined and minigraph_hwsku == 'ACS-MSN2700' @@ -37,3 +47,13 @@ - name: Remove existing ip from ptf host script: roles/test/files/helpers/remove_ip.sh delegate_to: "{{ ptf_host }}" + + - name: Restore LLDP Daemon + become: yes + supervisorctl: state=started name={{ item }} + vars: + ansible_shell_type: docker + ansible_python_interpreter: docker exec -i lldp python + with_items: + - lldpd + - lldp-syncd diff --git a/ansible/roles/test/tasks/copp_ptf.yml b/ansible/roles/test/tasks/copp_ptf.yml index 60509e33f0c..e9fd8033a8b 100644 --- a/ansible/roles/test/tasks/copp_ptf.yml +++ b/ansible/roles/test/tasks/copp_ptf.yml @@ -1,6 +1,6 @@ # FIXME: Use one common ptf_run.yml. Merge this file with sai_ptf.yml - name: "{{ test_name }}" - shell: ptf --test-dir saitests {{ test_path }} --qlen=10000 --platform nn -t "verbose=True;dst_mac='{{ ansible_Ethernet0['macaddress'] }}';" --device-socket 0-3@tcp://127.0.0.1:10900 --device-socket 1-3@tcp://{{ ansible_eth0['ipv4']['address'] }}:10900 --disable-ipv6 --disable-vxlan --disable-geneve --disable-erspan --disable-mpls --disable-nvgre 2>&1 + shell: ptf --test-dir saitests {{ test_path }} --qlen=100000 --platform nn -t "verbose=True" --device-socket 0-3@tcp://127.0.0.1:10900 --device-socket 1-3@tcp://{{ ansible_eth0['ipv4']['address'] }}:10900 --disable-ipv6 --disable-vxlan --disable-geneve --disable-erspan --disable-mpls --disable-nvgre 2>&1 args: chdir: /root delegate_to: "{{ ptf_host }}" diff --git a/ansible/roles/test/tasks/ecmp.yml b/ansible/roles/test/tasks/ecmp.yml index 654e47de22b..930adc26b92 100644 --- a/ansible/roles/test/tasks/ecmp.yml +++ b/ansible/roles/test/tasks/ecmp.yml @@ -1,7 +1,34 @@ - block: + - name: Ensure LLDP Daemon stopped + become: yes + supervisorctl: state=stopped name={{ item }} + vars: + ansible_shell_type: docker + ansible_python_interpreter: docker exec -i lldp python + with_items: + - lldp-syncd + - lldpd + + - name: Disable bgpd + become: yes + lineinfile: dest=/etc/quagga/daemons + regexp=^bgpd=.*$ + line='bgpd=no' + notify: + - Restart Quagga Daemon + vars: + ansible_shell_type: docker + ansible_python_interpreter: docker exec -i bgp python + + - meta: flush_handlers + - fail: msg="Please set ptf_host variable" when: ptf_host is not defined + - name: copy portmap + copy: src={{ ptf_portmap }} dest=/root + delegate_to: "{{ ptf_host }}" + - name: Remove existing ip from ptf host script: roles/test/files/helpers/remove_ip.sh delegate_to: "{{ ptf_host }}" @@ -10,6 +37,28 @@ script: roles/test/files/helpers/add_ip.sh delegate_to: "{{ ptf_host }}" + - name: Send pings from the ptf host {{ ptf_host }} to the target host {{ ansible_host }} + command: ping -c 5 10.0.0.{{ item }} + failed_when: False + with_sequence: start=1 end=63 stride=2 + + - name: Check ips on the ptf host + command: /sbin/ifconfig -a + delegate_to: "{{ ptf_host }}" + failed_when: False + register: out + + - name: Output of ips on ptf host {{ ptf_host }} + debug: var=out.stdout_lines + + - name: Check arp table on the ptf host + command: arp -an + failed_when: False + register: out + + - name: Output of the arp table on ptf host {{ ptf_host }} + debug: var=out.stdout_lines + - name: copy the test to ptf container copy: src=roles/test/files/saitests dest=/root delegate_to: "{{ ptf_host }}" @@ -17,6 +66,32 @@ - name: Install routes on the switch script: roles/test/files/helpers/add_routes.sh + - pause: seconds=10 + + - name: Check ips on the target host + command: /sbin/ifconfig -a + failed_when: False + register: out + + - name: Output of ips on target host {{ ansible_host }} + debug: var=out.stdout_lines + + - name: Check routes on the target host + command: ip route + failed_when: False + register: out + + - name: Output of routes on target host {{ ansible_host }} + debug: var=out.stdout_lines + + - name: Check arp table on the target host + command: arp -an + failed_when: False + register: out + + - name: Output of the arp table on target host {{ ansible_host }} + debug: var=out.stdout_lines + - include: qos_sai_ptf.yml vars: test_name: ECMP test @@ -31,3 +106,26 @@ - name: Remove existing ip from ptf host script: roles/test/files/helpers/remove_ip.sh delegate_to: "{{ ptf_host }}" + + - name: Restore LLDP Daemon + become: yes + supervisorctl: state=started name={{ item }} + vars: + ansible_shell_type: docker + ansible_python_interpreter: docker exec -i lldp python + with_items: + - lldpd + - lldp-syncd + + - name: Enable bgpd + become: yes + lineinfile: dest=/etc/quagga/daemons + regexp=^bgpd=.*$ + line='bgpd=yes' + notify: + - Restart Quagga Daemon + vars: + ansible_shell_type: docker + ansible_python_interpreter: docker exec -i bgp python + + - meta: flush_handlers diff --git a/ansible/roles/test/tasks/saiserver.yml b/ansible/roles/test/tasks/saiserver.yml new file mode 100644 index 00000000000..d6bf6805bed --- /dev/null +++ b/ansible/roles/test/tasks/saiserver.yml @@ -0,0 +1,70 @@ +# This Playbook would run saiserver-test on all the devices. +# +# Examples of running saiserver-test with this playbook: +# +## Run test sail3.L3IPv4HostTest on saiserver switch str-s6000-acs-9 and ptf_host 10.3.155.177 +# ansible-playbook -i str --limit str-s6000-acs-9 test.yml -b --ask-vault-pass -e "ptf_host=10.3.155.177" --e "tests=sail3.L3IPv4HostTest" --tags saiserver + + +# Stop syncd and deploy saiserver (only for SAI testing purpose) +- name: Stop syncd container + include: ../../sonic-common/tasks/sonicdocker.yml + vars: + docker_container: syncd + docker_image: "{{ image_id_syncd if sonic_asic_type!='mellanox' else image_id_syncd_mlnx }}" + docker_privileged: yes + docker_state: stopped + when: no_deploy_saiserver is not defined + +- name: Start saiserver docker container + include: ../../sonic-common/tasks/sonicdocker.yml + vars: + docker_container: saiserver + docker_image: "{{ image_id_saiserver if sonic_asic_type!='mellanox' else image_id_saiserver_mlnx }}" + docker_privileged: yes + docker_state: reloaded + when: no_deploy_saiserver is not defined + +- name: Wait to make sure saiserver is started + wait_for: timeout=20 + +- name: Run SAI Test + shell: ptf --test-dir /usr/share/ptf-tests {{ tests | default ("")}} -t "server='{{ ansible_host }}';port_map_file='/etc/ptf/default_interface_to_front_map.ini'" --platform remote {{ extra_options | default("")}} 2>&1 + args: + chdir: /root + delegate_to: "{{ ptf_host }}" + failed_when: False + register: out + +- debug: var=out.stdout_lines + +- name: Stop saiserver docker container + include: ../../sonic-common/tasks/sonicdocker.yml + vars: + docker_container: saiserver + docker_image: "{{ image_id_saiserver if sonic_asic_type!='mellanox' else image_id_saiserver_mlnx }}" + docker_privileged: yes + docker_state: stopped + when: no_deploy_saiserver is not defined + +- name: Restart syncd container + include: ../../sonic-common/tasks/sonicdocker.yml + vars: + docker_container: syncd + docker_image: "{{ image_id_syncd if sonic_asic_type!='mellanox' else image_id_syncd_mlnx }}" + docker_privileged: yes + docker_state: started + when: no_deploy_saiserver is not defined + +- name: Restart orchagent container + include: ../../sonic-common/tasks/sonicdocker.yml + vars: + docker_container: orchagent + docker_image: "{{ image_id_orchagent if sonic_asic_type!='mellanox' else image_id_orchagent_mlnx }}" + docker_privileged: yes + docker_state: restarted + when: no_deploy_saiserver is not defined + +- fail: msg="Failed test SAI Test" + when: out.rc != 0 + diff --git a/ansible/roles/test/tasks/sensors_check.yml b/ansible/roles/test/tasks/sensors_check.yml new file mode 120000 index 00000000000..a0436103e08 --- /dev/null +++ b/ansible/roles/test/tasks/sensors_check.yml @@ -0,0 +1 @@ +../../sonic-common/tasks/sensors_check.yml \ No newline at end of file diff --git a/ansible/roles/test/templates/etc/systemd/system/orchagent.j2 b/ansible/roles/test/templates/etc/systemd/system/orchagent.j2 new file mode 120000 index 00000000000..58f17a470aa --- /dev/null +++ b/ansible/roles/test/templates/etc/systemd/system/orchagent.j2 @@ -0,0 +1 @@ +../../../../../sonicv2/templates/etc/systemd/system/orchagent.j2 \ No newline at end of file diff --git a/ansible/roles/test/templates/etc/systemd/system/saiserver.j2 b/ansible/roles/test/templates/etc/systemd/system/saiserver.j2 new file mode 100644 index 00000000000..1f3ffcba7a3 --- /dev/null +++ b/ansible/roles/test/templates/etc/systemd/system/saiserver.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=saiserver container +Conflicts=sswsyncd.service syncd.service + +[Service] +User=root +{% if sonic_hwsku == 'ACS-MSN2700' %} +ExecStartPre=/etc/init.d/sxdkernel start +{% endif %} +ExecStart=/usr/bin/docker start -a saiserver +ExecStop=/usr/bin/docker stop saiserver +{% if sonic_hwsku == 'ACS-MSN2700' %} +ExecStopPost=/etc/init.d/sxdkernel stop +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/ansible/roles/test/templates/etc/systemd/system/syncd.j2 b/ansible/roles/test/templates/etc/systemd/system/syncd.j2 new file mode 120000 index 00000000000..5c5e39c3747 --- /dev/null +++ b/ansible/roles/test/templates/etc/systemd/system/syncd.j2 @@ -0,0 +1 @@ +../../../../../sonicv2/templates/etc/systemd/system/syncd.j2 \ No newline at end of file