diff --git a/ansible/lab b/ansible/lab index 389ad363e7..806ea9bd3b 100644 --- a/ansible/lab +++ b/ansible/lab @@ -10,6 +10,7 @@ all: sonic_s6000: sonic_s6100: sonic_a7260: + sonic_multi_asic: fanout: hosts: str-7260-10: @@ -98,3 +99,12 @@ sonic_a7260: lab-a7260-01: ansible_host: 10.251.0.191 hwsku: Arista-7260CX3-D108C8 + +sonic_multi_asic: + vars: + hwsku: msft_multi_asic_vs + iface_speed: 40000 + hosts: + vlab-07: + ansible_host: 10.250.0.109 + ansible_hostv6: fec0::ffff:afa:7 diff --git a/ansible/library/port_alias.py b/ansible/library/port_alias.py index 289d00de0f..a214f69426 100755 --- a/ansible/library/port_alias.py +++ b/ansible/library/port_alias.py @@ -8,17 +8,25 @@ from itertools import groupby from collections import defaultdict +try: + from sonic_py_common import multi_asic +except ImportError: + print("Failed to import multi_asic") + DOCUMENTATION = ''' module: port_alias.py Ansible_version_added: 2.0.0.2 short_description: Find SONiC device port alias mapping if there is alias mapping Description: - Minigraph file is using SONiC deivce alias to describe the interface name, it's vendor and and hardware platform dependent + Minigraph file is using SONiC device alias to describe the interface name, it's vendor and and hardware platform dependent This module is used to find the correct port_config.ini for the hwsku and return Ansible ansible_facts.port_alias The definition of this mapping is specified in http://github.com/azure/sonic-buildimage/device You should build docker-sonic-mgmt from sonic-buildimage and run Ansible from sonic-mgmt docker container + For multi-asic platforms, port_config.ini for each asic will be parsed to get the port_alias information. + When bringing up the testbed, port-alias will only contain external interfaces, so that vs image can come up with + external interfaces. Input: - hwsku + hwsku num_asic Return Ansible_facts: port_alias: SONiC interface name or SONiC interface alias if alias is available @@ -27,7 +35,7 @@ EXAMPLES = ''' - name: get hardware interface name - port_alias: hwsku='ACS-MSN2700' + port_alias: hwsku='ACS-MSN2700' num_asic=1 ''' RETURN = ''' @@ -40,7 +48,7 @@ ### Here are the expectation of files of device port_config.ini located, in case changed please modify it here FILE_PATH = '/usr/share/sonic/device' PORTMAP_FILE = 'port_config.ini' -ALLOWED_HEADER = ['name', 'lanes', 'alias', 'index', 'speed'] +ALLOWED_HEADER = ['name', 'lanes', 'alias', 'index', 'asic_port_name', 'role', 'speed'] MACHINE_CONF = '/host/machine.conf' ONIE_PLATFORM_KEY = 'onie_platform' @@ -69,27 +77,31 @@ def get_platform_type(self): return value return None - def get_portconfig_path(self): + def get_portconfig_path(self, asic_id=None): platform = self.get_platform_type() if platform is None: return None - portconfig = os.path.join(FILE_PATH, platform, self.hwsku, PORTMAP_FILE) + if asic_id is None: + portconfig = os.path.join(FILE_PATH, platform, self.hwsku, PORTMAP_FILE) + else: + portconfig = os.path.join(FILE_PATH, platform, self.hwsku, str(asic_id), PORTMAP_FILE) if os.path.exists(portconfig): return portconfig return None - def get_portmap(self): + def get_portmap(self, asic_id=None): aliases = [] portmap = {} aliasmap = {} portspeed = {} - filename = self.get_portconfig_path() + filename = self.get_portconfig_path(asic_id) if filename is None: raise Exception("Something wrong when trying to find the portmap file, either the hwsku is not available or file location is not correct") with open(filename) as f: lines = f.readlines() alias_index = -1 speed_index = -1 + role_index = -1 while len(lines) != 0: line = lines.pop(0) if re.match('^#', line): @@ -101,33 +113,67 @@ def get_portmap(self): alias_index = index if 'speed' in text: speed_index = index + if 'role' in text: + role_index = index else: if re.match('^Ethernet', line): mapping = line.split() name = mapping[0] + if (role_index != -1) and (len(mapping) > role_index): + role = mapping[role_index] + else: + role = 'Ext' if alias_index != -1 and len(mapping) > alias_index: alias = mapping[alias_index] else: alias = name - aliases.append(alias) - portmap[name] = alias - aliasmap[alias] = name - if (speed_index != -1) and (len(mapping) > speed_index): - portspeed[alias] = mapping[speed_index] + if role == 'Ext': + aliases.append(alias) + portmap[name] = alias + aliasmap[alias] = name + if (speed_index != -1) and (len(mapping) > speed_index): + portspeed[alias] = mapping[speed_index] return (aliases, portmap, aliasmap, portspeed) def main(): module = AnsibleModule( argument_spec=dict( - hwsku=dict(required=True, type='str') + hwsku=dict(required=True, type='str'), + num_asic=dict(type='int', required=False) ), supports_check_mode=True ) m_args = module.params try: + aliases = [] + portmap = {} + aliasmap = {} + portspeed = {} allmap = SonicPortAliasMap(m_args['hwsku']) - (aliases, portmap, aliasmap, portspeed) = allmap.get_portmap() + # When this script is invoked on sonic-mgmt docker, num_asic + # parameter is passed. + if m_args['num_asic'] is not None: + num_asic = m_args['num_asic'] + else: + # When this script is run on the device, num_asic parameter + # is not passed. + try: + num_asic = multi_asic.get_num_asics() + except Exception, e: + num_asic = 1 + for asic_id in range(num_asic): + if num_asic == 1: + asic_id = None + (aliases_asic, portmap_asic, aliasmap_asic, portspeed_asic) = allmap.get_portmap(asic_id) + if aliases_asic is not None: + aliases.extend(aliases_asic) + if portmap_asic is not None: + portmap.update(portmap_asic) + if aliasmap_asic is not None: + aliasmap.update(aliasmap_asic) + if portspeed_asic is not None: + portspeed.update(portspeed_asic) module.exit_json(ansible_facts={'port_alias': aliases, 'port_name_map': portmap, 'port_alias_map': aliasmap, diff --git a/ansible/roles/vm_set/library/sonic_kickstart.py b/ansible/roles/vm_set/library/sonic_kickstart.py index cf19fdfe12..8d268e98e5 100644 --- a/ansible/roles/vm_set/library/sonic_kickstart.py +++ b/ansible/roles/vm_set/library/sonic_kickstart.py @@ -118,6 +118,13 @@ def session(new_params): ('ip route', [r'#']), ('echo %s:%s | chpasswd' % (str(new_params['login']), str(new_params['new_password'])), [r'#']), ] + # For multi-asic VS there is no default config generated. + # interfaces-config service will not add eth0 IP address as there + # no default config. Multiple SWSS service will not start until + # topology service is loaded. Hence remove swss check and proceed + # with eth0 IP address assignment. + if int(new_params['num_asic']) > 1: + seq.pop(0) curtime = datetime.datetime.now().isoformat() debug = MyDebug('/tmp/debug.%s.%s.txt' % (new_params['hostname'], curtime), enabled=True) @@ -146,6 +153,7 @@ def main(): mgmt_ip = dict(required=True), mgmt_gw = dict(required=True), new_password = dict(required=True), + num_asic = dict(required=True), )) try: diff --git a/ansible/roles/vm_set/tasks/start_sonic_vm.yml b/ansible/roles/vm_set/tasks/start_sonic_vm.yml index 3ac78e0a20..8e2a231ea4 100644 --- a/ansible/roles/vm_set/tasks/start_sonic_vm.yml +++ b/ansible/roles/vm_set/tasks/start_sonic_vm.yml @@ -14,6 +14,8 @@ mgmt_ip_address: " {{ hostvars[dut_name]['ansible_host'] }}" mgmt_gw: "{{ vm_mgmt_gw | default(mgmt_gw) }}" serial_port: "{{ hostvars[dut_name]['serial_port'] }}" + hwsku: "{{ hostvars[dut_name].hwsku }}" + num_asic: "{{ hostvars[dut_name]['num_asics'] | default(1) }}" - name: Device debug output debug: msg="hostname = {{ dut_name }} serial port = {{ serial_port }} ip = {{ mgmt_ip_address }}/{{ mgmt_prefixlen }} mgmt_gw = {{ mgmt_gw }}" @@ -27,7 +29,7 @@ when: not file_stat.stat.exists - name: Get DUT port alias - port_alias: hwsku={{ hostvars[dut_name].hwsku }} + port_alias: hwsku={{ hostvars[dut_name].hwsku }} num_asic={{ num_asic }} delegate_to: localhost - name: Define SONiC vm {{ dut_name }} @@ -54,6 +56,7 @@ mgmt_ip="{{ mgmt_ip_address }}/{{ mgmt_prefixlen }}" mgmt_gw={{ vm_mgmt_gw | default(mgmt_gw) }} new_password={{ sonic_password }} + num_asic={{ num_asic }} register: kickstart_output - name: Fail if kickstart gives error for {{ dut_name }} diff --git a/ansible/roles/vm_set/templates/sonic.xml.j2 b/ansible/roles/vm_set/templates/sonic.xml.j2 index 17bd19e649..54a97791aa 100644 --- a/ansible/roles/vm_set/templates/sonic.xml.j2 +++ b/ansible/roles/vm_set/templates/sonic.xml.j2 @@ -1,8 +1,13 @@ {{ dut_name }} +{% if hwsku == 'msft_multi_asic_vs' %} + 8 + 8 +{% else %} 3072000 3072000 4 +{% endif %} /machine diff --git a/ansible/veos_vtb b/ansible/veos_vtb index be33f9f379..4ab6b40ffc 100644 --- a/ansible/veos_vtb +++ b/ansible/veos_vtb @@ -34,6 +34,7 @@ all: vlab-04: vlab-05: vlab-06: + vlab-07: ptf: hosts: ptf-01: @@ -48,6 +49,9 @@ all: ptf-04: ansible_host: 10.250.0.109 ansible_hostv6: fec0::ffff:afa:9 + ptf-05: + ansible_host: 10.250.0.110 + ansible_hostv6: fec0::ffff:afa:a vars: ansible_user: root ansible_password: root @@ -87,8 +91,6 @@ all: type: kvm hwsku: Force10-S6000 serial_port: 9002 - ansible_password: password - ansible_user: admin vlab-05: ansible_host: 10.250.0.110 ansible_hostv6: fec0::ffff:afa:a @@ -105,6 +107,15 @@ all: serial_port: 9004 ansible_password: password ansible_user: admin + vlab-07: + ansible_host: 10.250.0.109 + ansible_hostv6: fec0::ffff:afa:9 + type: kvm + hwsku: msft_multi_asic_vs + serial_port: 9005 + num_asics: 6 + ansible_password: password + ansible_user: admin vlab-simx-01: ansible_host: 10.250.0.103 ansible_hostv6: fec0::ffff:afa:3 @@ -115,7 +126,7 @@ all: ansible_hostv6: fec0::ffff:afa:4 type: simx hwsku: MSN3700 - + # The groups below are helpers to limit running playbooks to a specific server only server_1: vars: diff --git a/ansible/vtestbed.csv b/ansible/vtestbed.csv index 48ece8bdf1..93a9f97c9b 100644 --- a/ansible/vtestbed.csv +++ b/ansible/vtestbed.csv @@ -4,3 +4,4 @@ vms-kvm-t0-64,vms6-1,t0-64,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64 vms-kvm-t1-lag,vms6-2,t1-lag,docker-ptf,ptf-02,10.250.0.106/24,fec0::ffff:afa:6/64,server_1,VM0104,[vlab-03],Tests virtual switch vm vms-kvm-t0-2,vms6-3,t0,docker-ptf,ptf-03,10.250.0.108/24,fec0::ffff:afa:8/64,server_1,VM0104,[vlab-04],Tests virtual switch vm vms-kvm-dual-t0,vms6-4,dualtor,docker-ptf,ptf-04,10.250.0.109/24,fec0::ffff:afa:9/64,server_1,VM0108,[vlab-05;vlab-06],Dual-TOR testbed +vms-kvm-multi-asic-t1-lag,vms6-4,t1-64-lag,docker-ptf,ptf-05,10.250.0.110/24,fec0::ffff:afa:a/64,server_1,VM0104,[vlab-07],Tests multi-asic virtual switch vm