├── .coveragerc ├── .gitignore ├── .py3k_excludefilelist ├── .pylint_excludefilelist ├── .pylint_excludes.yml ├── .pylintrc ├── LICENSE ├── Makefile ├── README.md ├── README.sysfs.md ├── arista ├── __init__.py ├── cli │ ├── __init__.py │ ├── actions │ │ ├── __init__.py │ │ ├── chassis │ │ │ ├── __init__.py │ │ │ ├── diag.py │ │ │ └── setup.py │ │ ├── clean.py │ │ ├── daemon.py │ │ ├── default.py │ │ ├── diag.py │ │ ├── dump.py │ │ ├── fabric │ │ │ ├── __init__.py │ │ │ ├── clean.py │ │ │ ├── diag.py │ │ │ ├── power.py │ │ │ └── setup.py │ │ ├── linecard │ │ │ ├── __init__.py │ │ │ ├── clean.py │ │ │ ├── diag.py │ │ │ ├── power.py │ │ │ ├── provision.py │ │ │ ├── reboot.py │ │ │ ├── reboot_cause.py │ │ │ └── setup.py │ │ ├── platform │ │ │ ├── __init__.py │ │ │ └── diag.py │ │ ├── platforms.py │ │ ├── reboot.py │ │ ├── reboot_cause.py │ │ ├── reset.py │ │ ├── setup.py │ │ ├── show │ │ │ ├── __init__.py │ │ │ ├── chassis │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ └── summary.py │ │ │ ├── fabric │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ ├── environment.py │ │ │ │ └── status.py │ │ │ ├── linecard │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ ├── environment.py │ │ │ │ ├── reboot_cause.py │ │ │ │ └── status.py │ │ │ ├── platform │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ ├── environment.py │ │ │ │ ├── power.py │ │ │ │ ├── reboot_cause.py │ │ │ │ └── xcvr.py │ │ │ └── supported.py │ │ ├── syseeprom.py │ │ └── watchdog.py │ ├── args │ │ ├── __init__.py │ │ ├── chassis │ │ │ ├── __init__.py │ │ │ ├── diag.py │ │ │ └── setup.py │ │ ├── clean.py │ │ ├── common.py │ │ ├── daemon.py │ │ ├── default.py │ │ ├── diag.py │ │ ├── dump.py │ │ ├── fabric │ │ │ ├── __init__.py │ │ │ ├── clean.py │ │ │ ├── diag.py │ │ │ ├── power.py │ │ │ └── setup.py │ │ ├── linecard │ │ │ ├── __init__.py │ │ │ ├── clean.py │ │ │ ├── diag.py │ │ │ ├── power.py │ │ │ ├── provision.py │ │ │ ├── reboot.py │ │ │ ├── reboot_cause.py │ │ │ └── setup.py │ │ ├── platform │ │ │ ├── __init__.py │ │ │ └── diag.py │ │ ├── platforms.py │ │ ├── reboot.py │ │ ├── reboot_cause.py │ │ ├── reset.py │ │ ├── setup.py │ │ ├── show │ │ │ ├── __init__.py │ │ │ ├── chassis │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ └── summary.py │ │ │ ├── fabric │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ ├── environment.py │ │ │ │ └── status.py │ │ │ ├── linecard │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ ├── environment.py │ │ │ │ ├── reboot_cause.py │ │ │ │ └── status.py │ │ │ ├── platform │ │ │ │ ├── __init__.py │ │ │ │ ├── eeprom.py │ │ │ │ ├── environment.py │ │ │ │ ├── power.py │ │ │ │ ├── reboot_cause.py │ │ │ │ └── xcvr.py │ │ │ └── supported.py │ │ ├── syseeprom.py │ │ └── watchdog.py │ ├── exception.py │ ├── fork.py │ ├── parser.py │ ├── show │ │ ├── __init__.py │ │ ├── card.py │ │ ├── eeprom.py │ │ ├── environment.py │ │ ├── power.py │ │ ├── reboot_cause.py │ │ └── xcvr.py │ └── tests │ │ ├── __init__.py │ │ └── cli_platforms.py ├── components │ ├── __init__.py │ ├── asic │ │ ├── __init__.py │ │ ├── bfn │ │ │ ├── __init__.py │ │ │ ├── tofino.py │ │ │ └── tofino2.py │ │ ├── dnx │ │ │ ├── __init__.py │ │ │ ├── jericho2.py │ │ │ ├── jericho2c.py │ │ │ └── ramon.py │ │ └── xgs │ │ │ ├── __init__.py │ │ │ ├── tomahawk.py │ │ │ ├── tomahawk2.py │ │ │ ├── tomahawk3.py │ │ │ ├── tomahawk4.py │ │ │ ├── tomahawk5.py │ │ │ ├── trident2.py │ │ │ ├── trident3.py │ │ │ └── trident4.py │ ├── cookie.py │ ├── cpld.py │ ├── cpu │ │ ├── __init__.py │ │ ├── amd │ │ │ ├── __init__.py │ │ │ ├── designware.py │ │ │ ├── k10temp.py │ │ │ ├── piix.py │ │ │ └── sbtsi.py │ │ ├── cormorant.py │ │ ├── crow.py │ │ ├── intel │ │ │ ├── __init__.py │ │ │ ├── coretemp.py │ │ │ └── pch.py │ │ ├── lorikeet.py │ │ ├── raven.py │ │ ├── redstart.py │ │ ├── rook.py │ │ └── shearwater.py │ ├── denali │ │ ├── __init__.py │ │ ├── card.py │ │ ├── chassis.py │ │ ├── desc.py │ │ ├── fabric.py │ │ ├── linecard.py │ │ ├── psu.py │ │ ├── supervisor.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── chassis.py │ ├── dpm │ │ ├── __init__.py │ │ ├── adm1266.py │ │ ├── pmbus.py │ │ └── ucd.py │ ├── ds125br.py │ ├── eeprom.py │ ├── lm73.py │ ├── lm75.py │ ├── max31790.py │ ├── max6581.py │ ├── max6658.py │ ├── max6697.py │ ├── microsemi.py │ ├── minke.py │ ├── pali.py │ ├── pca9541.py │ ├── pca9555.py │ ├── phy │ │ ├── __init__.py │ │ ├── b52.py │ │ ├── babbage.py │ │ ├── babbagelp.py │ │ └── broncos.py │ ├── plx.py │ ├── psu │ │ ├── __init__.py │ │ ├── arista.py │ │ ├── artesyn.py │ │ ├── dcdc.py │ │ ├── delta.py │ │ ├── ds460.py │ │ ├── emerson.py │ │ ├── fixed.py │ │ ├── helper.py │ │ └── liteon.py │ ├── rpc.py │ ├── scd.py │ ├── tests │ │ ├── __init__.py │ │ └── cookie.py │ ├── tmp464.py │ ├── tmp468.py │ ├── vrm │ │ ├── __init__.py │ │ ├── mp8796b.py │ │ ├── raa228228.py │ │ ├── sic450.py │ │ └── tps549d22.py │ ├── watchdog.py │ └── xcvr.py ├── core │ ├── __init__.py │ ├── asic.py │ ├── backtrace.py │ ├── bootloader.py │ ├── card.py │ ├── cause.py │ ├── component │ │ ├── __init__.py │ │ ├── component.py │ │ ├── i2c.py │ │ ├── pci.py │ │ ├── slot.py │ │ └── unmanaged.py │ ├── config.py │ ├── cooling.py │ ├── cpu.py │ ├── daemon.py │ ├── desc.py │ ├── diag.py │ ├── domain.py │ ├── driver │ │ ├── __init__.py │ │ ├── kernel │ │ │ ├── __init__.py │ │ │ ├── i2c.py │ │ │ ├── pci.py │ │ │ └── sysfs.py │ │ └── user │ │ │ ├── __init__.py │ │ │ ├── gpio.py │ │ │ └── i2c.py │ ├── dynload.py │ ├── exception.py │ ├── fabric.py │ ├── fan.py │ ├── fixed.py │ ├── hwapi.py │ ├── i2c_utils.py │ ├── inventory.py │ ├── linecard.py │ ├── log.py │ ├── metainventory.py │ ├── modular.py │ ├── onie.py │ ├── pci.py │ ├── platform.py │ ├── port.py │ ├── prefdl.py │ ├── provision.py │ ├── psu.py │ ├── quirk.py │ ├── reboot.py │ ├── register.py │ ├── sku.py │ ├── supervisor.py │ ├── tests │ │ ├── __init__.py │ │ ├── cause.py │ │ ├── components.py │ │ ├── cooling.py │ │ ├── fabrics.py │ │ ├── hwapi.py │ │ ├── inventory.py │ │ ├── linecards.py │ │ ├── mockchassis.py │ │ ├── mockinv.py │ │ ├── pci.py │ │ ├── platform_register.py │ │ ├── platforms.py │ │ ├── port.py │ │ ├── prefdl.py │ │ ├── psu.py │ │ ├── psu_models.py │ │ ├── registers.py │ │ ├── thermal.py │ │ ├── utils.py │ │ └── xcvr.py │ ├── thermal_control.py │ ├── types.py │ ├── utils.py │ ├── version.py │ └── xcvr.py ├── daemon │ ├── __init__.py │ ├── cookies.py │ ├── dpm.py │ ├── jsonrpc.py │ ├── led.py │ ├── mac.py │ ├── quirk.py │ ├── seu.py │ └── storage.py ├── descs │ ├── __init__.py │ ├── cause.py │ ├── fan.py │ ├── gpio.py │ ├── led.py │ ├── psu.py │ ├── rail.py │ ├── reset.py │ ├── sensor.py │ ├── tests │ │ ├── __init__.py │ │ └── types.py │ └── xcvr.py ├── drivers │ ├── __init__.py │ ├── cookie.py │ ├── coretemp.py │ ├── cpld.py │ ├── crow.py │ ├── dpm │ │ ├── __init__.py │ │ ├── adm1266.py │ │ ├── pmbus.py │ │ └── ucd.py │ ├── ds125br.py │ ├── ds460.py │ ├── eeprom.py │ ├── k10temp.py │ ├── lm73.py │ ├── lm75.py │ ├── max31790.py │ ├── max6581.py │ ├── max6658.py │ ├── max6697.py │ ├── microsemi.py │ ├── minke.py │ ├── pali.py │ ├── pca9541.py │ ├── pca9555.py │ ├── pch.py │ ├── pci.py │ ├── plx.py │ ├── pmbus.py │ ├── raven.py │ ├── rook.py │ ├── rpc.py │ ├── sbtsi.py │ ├── scd │ │ ├── __init__.py │ │ ├── cause.py │ │ ├── driver.py │ │ ├── programmable.py │ │ ├── register.py │ │ ├── seu.py │ │ ├── sram.py │ │ └── watchdog.py │ ├── tmp468.py │ ├── vrm │ │ ├── __init__.py │ │ ├── sic450.py │ │ └── tps549d22.py │ └── xcvr.py ├── inventory │ ├── __init__.py │ ├── fan.py │ ├── gpio.py │ ├── interrupt.py │ ├── led.py │ ├── phy.py │ ├── powercycle.py │ ├── programmable.py │ ├── psu.py │ ├── rail.py │ ├── reloadcause.py │ ├── reset.py │ ├── seu.py │ ├── slot.py │ ├── temp.py │ ├── watchdog.py │ └── xcvr.py ├── libs │ ├── __init__.py │ ├── benchmark.py │ ├── config.py │ ├── date.py │ ├── fs.py │ ├── i2c.py │ ├── integer.py │ ├── onie.py │ ├── pci.py │ ├── ping.py │ ├── procfs.py │ ├── pyshell.py │ ├── python.py │ ├── retry.py │ └── wait.py ├── platforms │ ├── __init__.py │ ├── alhambra.py │ ├── blackhawk.py │ ├── blackhawktd4.py │ ├── blackhawkth4.py │ ├── catalina.py │ ├── chassis │ │ ├── __init__.py │ │ ├── camp.py │ │ ├── maunakea.py │ │ ├── northface.py │ │ ├── tuba.py │ │ └── yuba.py │ ├── clearlake.py │ ├── cloverdale.py │ ├── cpu │ │ ├── __init__.py │ │ ├── cormorant.py │ │ ├── crow.py │ │ ├── hedgehog.py │ │ ├── lorikeet.py │ │ ├── prairie.py │ │ ├── puffin.py │ │ ├── redstart.py │ │ ├── rook.py │ │ ├── shearwater.py │ │ ├── skylark.py │ │ ├── sprucefish.py │ │ └── woodpecker.py │ ├── fabric │ │ ├── __init__.py │ │ ├── brooks.py │ │ ├── dragonfly.py │ │ └── eldridge.py │ ├── gardena.py │ ├── linecard │ │ ├── __init__.py │ │ ├── clearwater.py │ │ ├── clearwater2.py │ │ └── wolverine.py │ ├── lodoga.py │ ├── marysville.py │ ├── mineral.py │ ├── moby.py │ ├── moranda.py │ ├── pikez.py │ ├── quartz.py │ ├── quicksilver.py │ ├── quicksilverr.py │ ├── silverstrand.py │ ├── smartsville.py │ ├── supervisor │ │ ├── __init__.py │ │ └── otterlake.py │ ├── upperlake.py │ └── woodleaf.py ├── tests │ ├── __init__.py │ ├── logging.py │ ├── selftest.py │ └── testing.py └── utils │ ├── __init__.py │ ├── rpc │ ├── __init__.py │ ├── api.py │ ├── client.py │ ├── constants.py │ ├── context.py │ ├── server.py │ └── tests │ │ ├── __init__.py │ │ ├── api.py │ │ ├── client.py │ │ └── server.py │ ├── sonic_eeprom.py │ ├── sonic_leds.py │ ├── sonic_platform │ ├── __init__.py │ ├── chassis.py │ ├── common.py │ ├── component.py │ ├── eeprom.py │ ├── event.py │ ├── fan.py │ ├── fan_drawer.py │ ├── module.py │ ├── pcie.py │ ├── platform.py │ ├── psu.py │ ├── sfp.py │ ├── sfp_optoe.py │ ├── thermal.py │ ├── thermal_action.py │ ├── thermal_condition.py │ ├── thermal_helper.py │ ├── thermal_info.py │ ├── thermal_manager.py │ └── watchdog.py │ ├── sonic_psu.py │ ├── sonic_reboot.py │ ├── sonic_sfputil.py │ ├── sonic_ssd.py │ └── sonic_utils.py ├── debian ├── changelog ├── compat ├── control ├── copyright └── rules ├── debug-dump ├── arista-debug-helpers.sh ├── arista.cache ├── arista.dump ├── arista.environment ├── arista.fs ├── arista.misc └── arista.reboot-cause ├── lib ├── Makefile ├── sfp-eeprom-info-c-gen.py ├── sfp-eeprom.c └── sfp-eeprom.h ├── logrotate └── arista ├── pytest.ini ├── scripts ├── pylint-filter └── pylint-make-excludes ├── setup.py ├── sonic_platform └── __init__.py ├── src ├── Makefile ├── amax31790.c ├── crow-fan-driver.c ├── minke-fan-cpld.c ├── pali-fan-cpld.c ├── raven-fan-driver.c ├── rook-fan-cpld.c ├── rook-led-driver.c ├── scd-attrs.h ├── scd-fan.c ├── scd-fan.h ├── scd-gpio.c ├── scd-gpio.h ├── scd-hwmon.h ├── scd-led.c ├── scd-led.h ├── scd-main.c ├── scd-mdio.c ├── scd-mdio.h ├── scd-reset.c ├── scd-reset.h ├── scd-smbus-trace.h ├── scd-smbus.c ├── scd-smbus.h ├── scd-uart.c ├── scd-uart.h ├── scd-xcvr.c ├── scd-xcvr.h ├── scd.c ├── scd.h └── tmp468.c ├── systemd ├── platform-arista-chassis-network.service ├── platform-arista-chassis-provision.service ├── platform-arista-daemon.service ├── platform-arista-fabric.service ├── platform-arista-init-watchdog-start.service ├── platform-arista-init-watchdog-stop.service ├── platform-arista-linecard-network.service ├── platform-arista-linecard.service ├── platform-arista-pmon.service ├── platform-arista-reboot-cause.service ├── platform-arista-swss.service └── platform-arista.target ├── udev ├── 70-lc-network.rules └── 98-scd-uio.rules └── utils ├── arista ├── arista-chassis-network ├── arista-chassis-provision ├── boot-eos └── lc-interface-config /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = 3 | */tests/* 4 | arista/utils/* 5 | 6 | [report] 7 | exclude_lines = 8 | pragma: no cover 9 | def __repr__ 10 | raise NotImplementedError 11 | if __name__ == .__main__.: 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # kernel module build 2 | *.a 3 | *.o 4 | *.so 5 | *.o.d 6 | *.ko 7 | *.mod 8 | *.mod.c 9 | *.mod.o 10 | *.cmd 11 | Module.symvers 12 | modules.order 13 | 14 | # libs 15 | /lib/sfp-eeprom.inc 16 | 17 | # debian packaging 18 | *.debhelper 19 | *.log 20 | DEBIAN 21 | .tmp_versions 22 | .finished.build 23 | *.substvars 24 | 25 | # python 26 | *.pyc 27 | __pycache__/ 28 | /build 29 | /*.egg-info 30 | /venv* 31 | /.pybuild 32 | /.eggs/ 33 | /.pytest_cache/ 34 | 35 | # package related rules 36 | /install/ 37 | /debian/files 38 | /debian/drivers-sonic-platform-arista/ 39 | /debian/python-sonic-platform-arista/ 40 | /debian/python3-sonic-platform-arista/ 41 | /debian/sonic-platform-arista/ 42 | /arista/__version__.py 43 | -------------------------------------------------------------------------------- /.py3k_excludefilelist: -------------------------------------------------------------------------------- 1 | daemon 2 | rpc 3 | -------------------------------------------------------------------------------- /.pylint_excludefilelist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/.pylint_excludefilelist -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | profile=no 3 | persistent=no 4 | 5 | [MESSAGES CONTROL] 6 | disable-checker=Design,Similarities 7 | disable=invalid-name, 8 | missing-docstring, 9 | duplicate-code, 10 | too-few-public-methods, 11 | bad-continuation, 12 | no-self-use, 13 | fixme, 14 | no-absolute-import, 15 | superfluous-parens, 16 | too-many-ancestors, 17 | too-many-arguments, 18 | too-many-statements, 19 | too-many-locals, 20 | too-many-instance-attributes, 21 | too-many-branches, 22 | unnecessary-lambda-assignment, 23 | unnecessary-pass, 24 | consider-using-f-string, 25 | useless-object-inheritance, 26 | super-with-arguments, 27 | no-member, 28 | 29 | # Compatibility with pylint from older Debian releases 30 | unrecognized-option, 31 | useless-option-value, 32 | 33 | [BASIC] 34 | bad-functions=apply,input 35 | 36 | [TYPECHECK] 37 | ignored-classes=RegisterMap,FakeRegisterMap 38 | 39 | [VARIABLES] 40 | dummy-variables-rgx=_ 41 | 42 | [CLASSES] 43 | defining-attr-methods=__init__, 44 | __new__, 45 | setUp, 46 | setup_method, 47 | 48 | [MISCELLANEOUS] 49 | notes=FIXME,XXX,TODO 50 | 51 | [FORMAT] 52 | max-line-length=85 53 | indent-string=' ' 54 | indent-after-paren=3 55 | -------------------------------------------------------------------------------- /arista/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/__init__.py -------------------------------------------------------------------------------- /arista/cli/actions/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from ..args import getParser 5 | 6 | class Action(object): 7 | def __init__(self, func, parent, kwargs): 8 | self.func = func 9 | self.parent = parent 10 | self.kwargs = kwargs 11 | 12 | def registerAction(parser, **kwargs): 13 | '''Register an action function for a subparser''' 14 | parser = getParser(parser) 15 | def decorator(func): 16 | action = Action(func, parser, kwargs) 17 | parser.addAction(action) 18 | return func 19 | return decorator 20 | -------------------------------------------------------------------------------- /arista/cli/actions/chassis/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...exception import ActionError 6 | from ...args.chassis import chassisParser 7 | from ....core.supervisor import Supervisor 8 | 9 | @registerAction(chassisParser) 10 | def doChassis(ctx, args): 11 | if not isinstance(ctx.platform, Supervisor): 12 | raise ActionError('platform %s is not a supervisor' % ctx.platform) 13 | 14 | chassis = ctx.platform.getChassis() 15 | setattr(ctx, 'chassis', chassis) 16 | -------------------------------------------------------------------------------- /arista/cli/actions/chassis/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ..diag import doCommonDiagCli 6 | from ...args.chassis.diag import diagParser 7 | 8 | @registerAction(diagParser) 9 | def doChassisDiag(ctx, args): 10 | doCommonDiagCli([ctx.platform.getChassis()], args) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/chassis/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...args.chassis.setup import setupParser 6 | 7 | @registerAction(setupParser) 8 | def doSetup(ctx, args): 9 | print('TODO: setup for', ctx.chassis) 10 | -------------------------------------------------------------------------------- /arista/cli/actions/clean.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerAction 5 | from ..args.clean import cleanParser 6 | from ...core import utils 7 | from ...core.config import Config 8 | from ...core.log import getLogger 9 | 10 | logging = getLogger(__name__) 11 | 12 | @registerAction(cleanParser) 13 | def doClean(ctx, args): 14 | if args.reset: 15 | logging.debug('putting devices in reset') 16 | ctx.platform.resetIn() 17 | 18 | logging.debug('cleaning up platform') 19 | with utils.FileLock(Config().lock_file): 20 | ctx.platform.clean() 21 | -------------------------------------------------------------------------------- /arista/cli/actions/daemon.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerAction 5 | from ..args.daemon import daemonParser 6 | from ...core.log import getLogger 7 | from ...core.daemon import Daemon, getDaemonFeatureCls 8 | from ...core.supervisor import Supervisor 9 | 10 | logging = getLogger(__name__) 11 | 12 | @registerAction(daemonParser) 13 | def doDaemon(ctx, args): 14 | if isinstance(ctx.platform, Supervisor): 15 | ctx.platform.getChassis().loadAll() 16 | daemon = Daemon(ctx.platform) 17 | for featureCls in getDaemonFeatureCls(args.feature): 18 | if featureCls.runnable(daemon): 19 | logging.debug('daemon: loading feature %s', featureCls.NAME) 20 | daemon.addFeature(featureCls()) 21 | else: 22 | logging.debug('daemon: skipping feature %s', featureCls.NAME) 23 | daemon.run() 24 | -------------------------------------------------------------------------------- /arista/cli/actions/default.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | import os 5 | import sys 6 | 7 | from . import registerAction 8 | from ..args.default import defaultPlatformParser 9 | from ...core import utils 10 | from ...core.platform import getPlatform 11 | from ...core.log import getLogger 12 | 13 | logging = getLogger(__name__) 14 | 15 | def checkRootPermissions(): 16 | if utils.inSimulation(): 17 | return 18 | 19 | if os.geteuid() != 0: 20 | logging.error('You must be root to use this feature') 21 | sys.exit(1) 22 | 23 | @registerAction(defaultPlatformParser) 24 | def doDefaultPlatform(ctx, args): 25 | checkRootPermissions() 26 | platform = getPlatform(args.platform) 27 | setattr(ctx, 'platform', platform) 28 | -------------------------------------------------------------------------------- /arista/cli/actions/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | import json 5 | 6 | from ...core.diag import DiagContext 7 | from ...libs.pyshell import pyshell 8 | 9 | def doCommonDiagCli(components, args): 10 | diagCtx = DiagContext( 11 | performIo=not args.noIo, 12 | recursive=args.recursive, 13 | safe=args.safe, 14 | ) 15 | diagInfo = [] 16 | 17 | for component in components: 18 | if args.recursive: 19 | diagInfo.append(component.genDiag(diagCtx)) 20 | else: 21 | for c in component.iterComponents(): 22 | diagInfo.append(c.genDiag(diagCtx)) 23 | 24 | if args.pyshell: 25 | pyshell() 26 | else: 27 | ident = 3 if args.pretty else None 28 | print(json.dumps(diagInfo, indent=ident)) 29 | -------------------------------------------------------------------------------- /arista/cli/actions/dump.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.supervisor import Supervisor 3 | 4 | from ..args.dump import dumpParser 5 | from .diag import doCommonDiagCli 6 | 7 | from . import registerAction 8 | 9 | class DiagArgs(object): 10 | def __init__(self, noIo=False, recursive=True, pyshell=False, pretty=True): 11 | self.noIo = noIo 12 | self.recursive = recursive 13 | self.pyshell = pyshell 14 | self.pretty = pretty 15 | self.safe = True 16 | 17 | @registerAction(dumpParser) 18 | def doDump(ctx, args): 19 | args = DiagArgs() 20 | skus = [] 21 | if isinstance(ctx.platform, Supervisor): 22 | skus.append(ctx.platform.getChassis()) 23 | else: 24 | skus.append(ctx.platform) 25 | doCommonDiagCli(skus, args) 26 | -------------------------------------------------------------------------------- /arista/cli/actions/fabric/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...exception import ActionError 6 | from ...fork import processIterParentWait 7 | from ...args.fabric import fabricParser 8 | from ....core.supervisor import Supervisor 9 | 10 | @registerAction(fabricParser) 11 | def doFabric(ctx, args): 12 | if not isinstance(ctx.platform, Supervisor): 13 | raise ActionError('platform %s is not a supervisor' % ctx.platform) 14 | 15 | chassis = ctx.platform.getChassis() 16 | setattr(ctx, 'chassis', chassis) 17 | 18 | chassis.loadFabrics(args.id) 19 | 20 | fabrics = [] 21 | for fabric in chassis.iterFabrics(): 22 | if (fabric.slot.getPresence() and 23 | (args.id is None or fabric.slot.slotId in args.id)): 24 | fabrics.append(fabric) 25 | 26 | if args.parallel: 27 | for fabric in processIterParentWait(fabrics): 28 | setattr(ctx, 'fabrics', [fabric]) 29 | else: 30 | setattr(ctx, 'fabrics', fabrics) 31 | -------------------------------------------------------------------------------- /arista/cli/actions/fabric/clean.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...args.fabric.clean import cleanParser 6 | from ....core.log import getLogger 7 | 8 | logging = getLogger(__name__) 9 | 10 | @registerAction(cleanParser) 11 | def doClean(ctx, args): 12 | for fabric in ctx.fabrics: 13 | logging.debug('Cleaning %s', fabric) 14 | try: 15 | fabric.clean() 16 | if args.off: 17 | fabric.powerOnIs(False) 18 | except Exception as e: # pylint: disable=broad-except 19 | logging.warning('Failed to clean %s: %s', fabric, str(e)) 20 | 21 | -------------------------------------------------------------------------------- /arista/cli/actions/fabric/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ..diag import doCommonDiagCli 6 | from ...args.fabric.diag import diagParser 7 | 8 | @registerAction(diagParser) 9 | def doFabricDiag(ctx, args): 10 | doCommonDiagCli(ctx.fabrics, args) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/fabric/power.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...args.fabric.power import powerParser 4 | from ....core.log import getLogger 5 | 6 | logging = getLogger(__name__) 7 | 8 | @registerAction(powerParser) 9 | def doSetup(ctx, args): 10 | power = args.state == 'on' 11 | for fabric in ctx.fabrics: 12 | try: 13 | fabric.powerOnIs(power) 14 | except Exception as e: # pylint: disable=broad-except 15 | logging.error('Failed to power %s fabric %s: %s', args.state, 16 | fabric, str(e)) 17 | -------------------------------------------------------------------------------- /arista/cli/actions/fabric/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...args.fabric.setup import setupParser 6 | from ....core.component import Priority 7 | from ....core.log import getLogger 8 | 9 | logging = getLogger(__name__) 10 | 11 | def setupFabric(fabric, args): 12 | if args.early or not args.late: 13 | fabric.setup(Priority.defaultFilter) 14 | if args.late or not args.early: 15 | fabric.setup(Priority.backgroundFilter) 16 | if args.on: 17 | if fabric.poweredOn() and args.powerCycleIfOn: 18 | fabric.powerOnIs(False) 19 | fabric.powerOnIs(True) 20 | if args.early or not args.late: 21 | fabric.setupMain(Priority.defaultFilter) 22 | if args.late or not args.early: 23 | fabric.setupMain(Priority.backgroundFilter) 24 | 25 | @registerAction(setupParser) 26 | def doSetup(ctx, args): 27 | for fabric in ctx.fabrics: 28 | logging.debug('Setting up %s', fabric) 29 | try: 30 | setupFabric(fabric, args) 31 | except Exception as e: # pylint: disable=broad-except 32 | logging.warning('Failed to setup %s: %s', fabric, str(e)) 33 | 34 | -------------------------------------------------------------------------------- /arista/cli/actions/linecard/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...exception import ActionError 6 | from ...fork import processIterParentWait 7 | from ...args.linecard import linecardParser 8 | from ....core.supervisor import Supervisor 9 | 10 | @registerAction(linecardParser) 11 | def doLinecard(ctx, args): 12 | if not isinstance(ctx.platform, Supervisor): 13 | raise ActionError('platform %s is not a supervisor' % ctx.platform) 14 | 15 | chassis = ctx.platform.getChassis() 16 | setattr(ctx, 'chassis', chassis) 17 | 18 | chassis.loadLinecards(args.id) 19 | 20 | linecards = [] 21 | for linecard in chassis.iterLinecards(): 22 | if (linecard.slot.getPresence() and 23 | (args.id is None or linecard.slot.slotId in args.id)): 24 | linecards.append(linecard) 25 | 26 | if args.parallel: 27 | for linecard in processIterParentWait(linecards): 28 | setattr(ctx, 'linecards', [linecard]) 29 | else: 30 | setattr(ctx, 'linecards', linecards) 31 | -------------------------------------------------------------------------------- /arista/cli/actions/linecard/clean.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...args.linecard.clean import cleanParser 6 | from ....core.config import Config 7 | from ....core.log import getLogger 8 | from ....core.linecard import LCpuCtx 9 | 10 | logging = getLogger(__name__) 11 | 12 | def cleanLinecard(linecard, args, lcpu): 13 | linecard.clean() 14 | 15 | if not args.off: 16 | return 17 | 18 | if not Config().linecard_standby_only and lcpu: 19 | logging.warning('LCPU cannot be powered off in non standby mode') 20 | return 21 | 22 | lcpuCtx = None 23 | if lcpu: 24 | lcpuCtx = LCpuCtx() 25 | 26 | if not Config().linecard_standby_only or lcpu: 27 | linecard.powerOnIs(False, lcpuCtx=lcpuCtx) 28 | 29 | @registerAction(cleanParser) 30 | def doClean(ctx, args): 31 | lcpu = args.lcpu if args.lcpu is not None else Config().linecard_cpu_enable 32 | 33 | for linecard in ctx.linecards: 34 | logging.debug('Cleaning %s', linecard) 35 | try: 36 | cleanLinecard(linecard, args, lcpu) 37 | except Exception as e: # pylint: disable=broad-except 38 | logging.warning('Failed to clean %s: %s', linecard, str(e)) 39 | -------------------------------------------------------------------------------- /arista/cli/actions/linecard/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ..diag import doCommonDiagCli 6 | from ...args.linecard.diag import diagParser 7 | 8 | @registerAction(diagParser) 9 | def doLinecardDiag(ctx, args): 10 | doCommonDiagCli(ctx.linecards, args) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/linecard/power.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...args.linecard.power import powerParser 4 | from ....core.config import Config 5 | from ....core.log import getLogger 6 | from ....core.linecard import LCpuCtx 7 | 8 | logging = getLogger(__name__) 9 | 10 | @registerAction(powerParser) 11 | def doPower(ctx, args): 12 | power = args.state == 'on' 13 | 14 | lcpuCtx = None 15 | if args.lcpu is not None or Config().linecard_cpu_enable: 16 | lcpuCtx = LCpuCtx() 17 | 18 | for linecard in ctx.linecards: 19 | try: 20 | if lcpuCtx and not linecard.hasCpuModule(): 21 | logging.info('%s has no LCPU module, skipping...', linecard) 22 | continue 23 | 24 | if linecard.poweredOn() and args.powerCycleIfOn and power: 25 | linecard.powerOnIs(False, lcpuCtx=lcpuCtx) 26 | linecard.powerOnIs(power, lcpuCtx=lcpuCtx) 27 | except Exception as e: # pylint: disable=broad-except 28 | logging.error('Failed to power %s linecard %s: %s', args.state, 29 | linecard, str(e)) 30 | -------------------------------------------------------------------------------- /arista/cli/actions/linecard/provision.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...args.linecard.provision import provisionParser 6 | from ....core.log import getLogger 7 | 8 | logging = getLogger(__name__) 9 | 10 | @registerAction(provisionParser) 11 | def doProvision(ctx, args): 12 | for linecard in ctx.linecards: 13 | try: 14 | if not linecard.hasCpuModule(): 15 | logging.info('%s has no LCPU module, skipping...', linecard) 16 | continue 17 | if not linecard.poweredOn(): 18 | logging.info('%s is not powered on, skipping...', linecard) 19 | continue 20 | logging.debug('Setting provision mode to %s on %s', args.set, linecard) 21 | linecard.provisionIs(args.set) 22 | except Exception as e: # pylint: disable=broad-except 23 | logging.warning('Failed to set provision mode on %s: %s', linecard, str(e)) 24 | -------------------------------------------------------------------------------- /arista/cli/actions/linecard/reboot.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...args.linecard.reboot import rebootParser 4 | from ....core.log import getLogger 5 | from ....core.reboot import LinecardRebootManager 6 | 7 | logging = getLogger(__name__) 8 | 9 | @registerAction(rebootParser) 10 | def doReboot(ctx, args): 11 | chassis = ctx.platform.getChassis() 12 | lrm = LinecardRebootManager(chassis, ctx.linecards) 13 | lrm.rebootLinecards(args.mode) 14 | -------------------------------------------------------------------------------- /arista/cli/actions/linecard/reboot_cause.py: -------------------------------------------------------------------------------- 1 | from .. import registerAction 2 | from ...args.linecard.reboot_cause import rebootCauseParser 3 | from ....core import utils 4 | from ....core.config import Config 5 | from ....core.cause import getLinecardReloadCauseManager 6 | 7 | @registerAction(rebootCauseParser) 8 | def doRebootCause(ctx, args): 9 | if utils.inSimulation(): 10 | return 11 | 12 | for linecard in ctx.linecards: 13 | try: 14 | lock_file = Config().linecard_lock_file_pattern.format(linecard.getSlotId()) 15 | with utils.FileLock(lock_file): 16 | getLinecardReloadCauseManager(linecard, read=args.process) 17 | except Exception: # pylint: disable=broad-except 18 | print(f'Failed to read reboot-cause information from linecard {linecard}') 19 | -------------------------------------------------------------------------------- /arista/cli/actions/platform/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ...exception import ActionError 6 | from ...args.platform import platformParser 7 | 8 | @registerAction(platformParser) 9 | def doPlatform(ctx, args): 10 | pass 11 | -------------------------------------------------------------------------------- /arista/cli/actions/platform/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerAction 5 | from ..diag import doCommonDiagCli 6 | from ...args.platform.diag import diagParser 7 | 8 | @registerAction(diagParser) 9 | def doPlatformDiag(ctx, args): 10 | doCommonDiagCli([ctx.platform], args) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/platforms.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerAction 5 | from ..args.platforms import platformsParser 6 | from ...core.fixed import FixedSystem 7 | from ...core.platform import getPlatformSkus 8 | 9 | @registerAction(platformsParser, needsPlatform=False) 10 | def doPlatforms(ctx, args): 11 | print('supported platforms:') 12 | for plat, cls in sorted(getPlatformSkus().items()): 13 | if issubclass(cls, FixedSystem): 14 | print(' -', plat) 15 | -------------------------------------------------------------------------------- /arista/cli/actions/reboot.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerAction 5 | from ..args.reboot import rebootParser 6 | 7 | @registerAction(rebootParser) 8 | def doReboot(ctx, args): 9 | import arista.utils.sonic_reboot 10 | arista.utils.sonic_reboot.do_reboot(ctx.platform) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/reboot_cause.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerAction 5 | from ..args.reboot_cause import rebootCauseParser 6 | from ...core import utils 7 | from ...core.cause import getReloadCauseManager 8 | from ...core.config import Config 9 | 10 | @registerAction(rebootCauseParser) 11 | def doRebootCause(ctx, args): 12 | if utils.inSimulation(): 13 | return 14 | 15 | with utils.FileLock(Config().lock_file): 16 | rcm = getReloadCauseManager(ctx.platform, read=args.process) 17 | 18 | if args.history: 19 | causes = [report.cause for report in rcm.allReports()] 20 | else: 21 | report = rcm.lastReport() 22 | causes = [report.cause] if report else [] 23 | if not causes: 24 | print('No reboot cause detected') 25 | return 26 | print('Found reboot cause(s):') 27 | print('----------------------') 28 | for item in causes: 29 | print(item) 30 | -------------------------------------------------------------------------------- /arista/cli/actions/reset.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | import time 5 | 6 | from . import registerAction 7 | from ..args.reset import resetParser 8 | from ...core.log import getLogger 9 | 10 | logging = getLogger(__name__) 11 | 12 | @registerAction(resetParser) 13 | def doReset(ctx, args): 14 | resets = ctx.platform.getInventory().getResets() 15 | if args.reset_list: 16 | print('Reset Supported Devices:') 17 | print("{: <20} {: <20}".format('Name', 'Value')) 18 | for reset in sorted(resets): 19 | print("{: <20} {: <20}".format(reset, resets[reset].read())) 20 | return 0 21 | 22 | devices = args.device 23 | if not devices: 24 | devices = resets.keys() 25 | else: 26 | for device in devices: 27 | if device not in resets: 28 | logging.error('device %s does not exist', device) 29 | return 1 30 | 31 | if args.reset_out: 32 | for device in devices: 33 | resets[device].resetOut() 34 | elif args.reset_in: 35 | for device in devices: 36 | resets[device].resetIn() 37 | elif args.reset_toggle: 38 | for device in devices: 39 | resets[device].resetIn() 40 | time.sleep(args.reset_delay) 41 | for device in devices: 42 | resets[device].resetOut() 43 | else: 44 | logging.info('nothing to do') 45 | 46 | return 0 47 | -------------------------------------------------------------------------------- /arista/cli/actions/show/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...exception import ActionError 4 | from ...args.show import showParser 5 | 6 | from ...show import Show 7 | 8 | @registerAction(showParser) 9 | def doShow(ctx, args): 10 | outputFormat = Show.TXT 11 | if args.json: 12 | outputFormat = Show.JSON 13 | 14 | setattr(ctx, 'show', Show(outputFormat=outputFormat, args=args)) 15 | -------------------------------------------------------------------------------- /arista/cli/actions/show/chassis/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...chassis import doChassis 4 | from ....args.show.chassis import showChassisParser 5 | 6 | @registerAction(showChassisParser) 7 | def doShowChassis(ctx, args): 8 | doChassis(ctx, args) 9 | -------------------------------------------------------------------------------- /arista/cli/actions/show/chassis/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.chassis.eeprom import showChassisEepromParser 4 | from ....show.eeprom import ShowEeprom 5 | 6 | @registerAction(showChassisEepromParser) 7 | def doShowChassisEeprom(ctx, _args): 8 | ctx.show.addInventory(ctx.chassis.getEeprom()) 9 | ctx.show.render(ShowEeprom()) 10 | -------------------------------------------------------------------------------- /arista/cli/actions/show/fabric/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...fabric import doFabric 4 | from ....args.show.fabric import showFabricParser 5 | 6 | @registerAction(showFabricParser) 7 | def doShowFabric(ctx, args): 8 | doFabric(ctx, args) 9 | -------------------------------------------------------------------------------- /arista/cli/actions/show/fabric/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.fabric.eeprom import showFabricEepromParser 4 | from ....show.eeprom import ShowEeprom 5 | 6 | @registerAction(showFabricEepromParser) 7 | def doShowFabricEeprom(ctx, _args): 8 | for fabric in ctx.fabrics: 9 | ctx.show.addInventory(fabric.getEeprom(), SlotId=fabric.slot.slotId) 10 | ctx.show.render(ShowEeprom()) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/show/fabric/environment.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.fabric.environment import environmentParser 4 | from ....show.environment import ShowEnvironment 5 | 6 | @registerAction(environmentParser) 7 | def doShowEnvironment(ctx, args): 8 | for fabric in ctx.fabrics: 9 | ctx.show.addInventory(fabric.getInventory()) 10 | ctx.show.render(ShowEnvironment()) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/show/fabric/status.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.fabric.status import statusParser 4 | from ....show.card import ShowCardStatus 5 | 6 | @registerAction(statusParser) 7 | def doShowStatus(ctx, args): 8 | for fabric in ctx.fabrics: 9 | ctx.show.addInventory(fabric) 10 | ctx.show.render(ShowCardStatus()) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/show/linecard/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...linecard import doLinecard 4 | from ....args.show.linecard import showLinecardParser 5 | 6 | @registerAction(showLinecardParser) 7 | def doShowLinecard(ctx, args): 8 | doLinecard(ctx, args) 9 | -------------------------------------------------------------------------------- /arista/cli/actions/show/linecard/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.linecard.eeprom import showLinecardEepromParser 4 | from ....show.eeprom import ShowEeprom 5 | 6 | @registerAction(showLinecardEepromParser) 7 | def doShowLinecardEeprom(ctx, _args): 8 | for linecard in ctx.linecards: 9 | ctx.show.addInventory(linecard.getEeprom(), SlotId=linecard.slot.slotId) 10 | ctx.show.render(ShowEeprom()) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/show/linecard/environment.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.linecard.environment import environmentParser 4 | from ....show.environment import ShowEnvironment 5 | 6 | @registerAction(environmentParser) 7 | def doShowEnvironment(ctx, args): 8 | for linecard in ctx.linecards: 9 | ctx.show.addInventory(linecard.getInventory()) 10 | ctx.show.render(ShowEnvironment()) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/show/linecard/reboot_cause.py: -------------------------------------------------------------------------------- 1 | from .. import registerAction 2 | from ....args.show.linecard.reboot_cause import showRebootCauseParser 3 | from ....show.reboot_cause import ShowLinecardRebootCause 4 | 5 | # pylint: disable=unused-argument 6 | 7 | @registerAction(showRebootCauseParser) 8 | def doRebootCause(ctx, args): 9 | for linecard in ctx.linecards: 10 | ctx.show.addInventory(linecard) 11 | ctx.show.render(ShowLinecardRebootCause()) 12 | -------------------------------------------------------------------------------- /arista/cli/actions/show/linecard/status.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.linecard.status import statusParser 4 | from ....show.card import ShowCardStatus 5 | 6 | @registerAction(statusParser) 7 | def doShowStatus(ctx, args): 8 | for linecard in ctx.linecards: 9 | ctx.show.addInventory(linecard) 10 | ctx.show.render(ShowCardStatus()) 11 | -------------------------------------------------------------------------------- /arista/cli/actions/show/platform/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerAction 3 | from ...platform import doPlatform 4 | from ....args.show.platform import showPlatformParser 5 | 6 | @registerAction(showPlatformParser) 7 | def doShowPlatform(ctx, args): 8 | doPlatform(ctx, args) 9 | ctx.show.addPlatform(ctx.platform) 10 | -------------------------------------------------------------------------------- /arista/cli/actions/show/platform/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.platform.eeprom import showPlatformEepromParser 4 | from ....show.eeprom import ShowEeprom 5 | 6 | @registerAction(showPlatformEepromParser) 7 | def doShowPlatformEeprom(ctx, _args): 8 | ctx.show.addInventory(ctx.platform.getEeprom()) 9 | ctx.show.render(ShowEeprom()) 10 | -------------------------------------------------------------------------------- /arista/cli/actions/show/platform/environment.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.platform.environment import environmentParser 4 | from ....show.environment import ShowEnvironment 5 | 6 | @registerAction(environmentParser) 7 | def doShowEnvironment(ctx, args): 8 | ctx.show.addInventory(ctx.platform.getInventory()) 9 | ctx.show.render(ShowEnvironment()) 10 | -------------------------------------------------------------------------------- /arista/cli/actions/show/platform/power.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.platform.power import powerParser 4 | from ....show.power import ShowPower 5 | 6 | @registerAction(powerParser) 7 | def doShowPower(ctx, args): 8 | ctx.show.render(ShowPower()) 9 | -------------------------------------------------------------------------------- /arista/cli/actions/show/platform/reboot_cause.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.platform.reboot_cause import rebootCauseParser 4 | from ....show.reboot_cause import ShowPlatformRebootCause 5 | 6 | @registerAction(rebootCauseParser) 7 | def doShowEnvironment(ctx, args): 8 | ctx.show.render(ShowPlatformRebootCause()) 9 | -------------------------------------------------------------------------------- /arista/cli/actions/show/platform/xcvr.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerAction 3 | from ....args.show.platform.xcvr import xcvrParser 4 | from ....show.xcvr import ShowXcvr 5 | 6 | @registerAction(xcvrParser) 7 | def doShowXcvr(ctx, args): 8 | ctx.show.addInventory(ctx.platform.getInventory()) 9 | ctx.show.render(ShowXcvr()) 10 | -------------------------------------------------------------------------------- /arista/cli/actions/syseeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerAction 5 | from ..args.syseeprom import syseepromParser 6 | from ...core.platform import getSysEepromData 7 | 8 | @registerAction(syseepromParser) 9 | def doSysEeprom(ctx, args): 10 | for key, value in getSysEepromData().items(): 11 | print('%s: %s' % (key, value)) 12 | -------------------------------------------------------------------------------- /arista/cli/actions/watchdog.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerAction 5 | from ..args.watchdog import watchdogParser 6 | 7 | from ...core.log import getLogger 8 | 9 | logging = getLogger(__name__) 10 | 11 | @registerAction(watchdogParser) 12 | def doWatchdog(ctx, args): 13 | watchdogs = ctx.platform.getInventory().getWatchdogs() 14 | if not watchdogs: 15 | print("Watchdog not supported on this platform") 16 | return 0 17 | 18 | watchdog = watchdogs[0] 19 | if args.watchdog_status: 20 | st = watchdog.status() 21 | if st: 22 | kv = ' '.join('%s=%s' % (k, v) for k, v in st.items()) 23 | print("Watchdog status: %s" % kv) 24 | else: 25 | print("Watchdog status - error.") 26 | return 1 27 | elif args.watchdog_stop: 28 | logging.info('disabling the hardware watchdog') 29 | if not watchdog.stop(): 30 | logging.error('failed to stop the hardware watchdog') 31 | return 1 32 | else: 33 | logging.info('arming the hardware watchdog for %ds', args.watchdog_timeout) 34 | # Tens of milliseconds 35 | watchdog_timeout = args.watchdog_timeout * 100 36 | if watchdog_timeout > watchdog.MAX_TIMEOUT: 37 | logging.error('failed to arm the hardware watchdog: time value is too big') 38 | return 1 39 | if not watchdog.arm(watchdog_timeout): 40 | logging.error('failed to arm the hardware watchdog') 41 | return 1 42 | return 0 43 | 44 | -------------------------------------------------------------------------------- /arista/cli/args/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from collections import OrderedDict 5 | 6 | from ..parser import Parser 7 | from ...core.dynload import importSubmodules 8 | 9 | registeredParsers = OrderedDict() 10 | 11 | def registerParser(name, parent=None, **kwargs): 12 | '''Arguments to provide to a subparser''' 13 | parentParser = registeredParsers.get(parent) 14 | if parent is None and parentParser is None: 15 | parentParser = Parser(None, None, None, None) 16 | registeredParsers[None] = parentParser 17 | 18 | def decorator(func): 19 | parser = getParser(func) 20 | if not parser: 21 | # FIXME: due to dynamic loading, parent parsers can be reloaded 22 | # we therefore only add it if i 23 | parser = Parser(name, func, parentParser, kwargs) 24 | registeredParsers[func] = parser 25 | parentParser.addChild(parser) 26 | return func 27 | return decorator 28 | 29 | def getParsers(): 30 | return registeredParsers.values() 31 | 32 | def getParser(parser): 33 | for p in registeredParsers.values(): 34 | if p.parser is not None and \ 35 | p.parser.__name__ == parser.__name__ and \ 36 | p.parser.__module__ == parser.__module__: 37 | return p 38 | return None 39 | 40 | def getRootParser(): 41 | return registeredParsers[None] 42 | 43 | # dynamically load all parsers 44 | __all__ = importSubmodules(__package__).keys() 45 | -------------------------------------------------------------------------------- /arista/cli/args/chassis/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..default import defaultPlatformParser 6 | 7 | @registerParser('chassis', parent=defaultPlatformParser, 8 | help='Chassis related features') 9 | def chassisParser(parser): 10 | pass 11 | -------------------------------------------------------------------------------- /arista/cli/args/chassis/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..diag import addDiagCommonParser 6 | from ..chassis import chassisParser 7 | 8 | @registerParser('diag', parent=chassisParser, 9 | help='dump diag information for the chassis') 10 | def diagParser(parser): 11 | addDiagCommonParser(parser) 12 | -------------------------------------------------------------------------------- /arista/cli/args/chassis/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from . import chassisParser 6 | 7 | @registerParser('setup', parent=chassisParser, 8 | help='setup drivers for this platform') 9 | def setupParser(parser): 10 | pass 11 | -------------------------------------------------------------------------------- /arista/cli/args/clean.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | from .default import defaultPlatformParser 6 | 7 | @registerParser('clean', parent=defaultPlatformParser, 8 | help='unload drivers for this platform') 9 | def cleanParser(parser): 10 | parser.add_argument('-r', '--reset', action='store_true', 11 | help='put devices in reset before cleanup') 12 | -------------------------------------------------------------------------------- /arista/cli/args/common.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | def addPriorityArgs(parser): 5 | parser.add_argument('--early', action='store_true', 6 | help='perform early initialisation, tied to the switch chip') 7 | parser.add_argument('--late', action='store_true', 8 | help='perform late initialisation, tied to the platform') 9 | 10 | -------------------------------------------------------------------------------- /arista/cli/args/daemon.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | from .default import defaultPlatformParser 6 | 7 | @registerParser('daemon', parent=defaultPlatformParser, 8 | help='run arista daemon to monitor the hardware') 9 | def daemonParser(parser): 10 | parser.add_argument('-f', '--feature', action='append', 11 | help='Name of the features to run, default all') 12 | -------------------------------------------------------------------------------- /arista/cli/args/default.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | 6 | @registerParser(None) 7 | def defaultPlatformParser(parser): 8 | pass 9 | -------------------------------------------------------------------------------- /arista/cli/args/diag.py: -------------------------------------------------------------------------------- 1 | def addDiagCommonParser(parser): 2 | parser.add_argument('-n', '--noIo', action='store_true', 3 | help='do not perform any IO to generate the diag info') 4 | parser.add_argument('-r', '--recursive', action='store_true', 5 | help='generate a recursive output rather than a flat one') 6 | parser.add_argument('-p', '--pretty', action='store_true', 7 | help='generate a pretty json output') 8 | parser.add_argument('-s', '--safe', action='store_true', 9 | help='try to avoid asserts on error') 10 | parser.add_argument('--pyshell', action='store_true', 11 | help='start a pyshell instead of printing output') 12 | -------------------------------------------------------------------------------- /arista/cli/args/dump.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser 3 | from .default import defaultPlatformParser 4 | 5 | @registerParser('dump', parent=defaultPlatformParser, 6 | help='dump information on this platform') 7 | def dumpParser(parser): 8 | pass 9 | -------------------------------------------------------------------------------- /arista/cli/args/fabric/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..default import defaultPlatformParser 6 | 7 | @registerParser('fabric', parent=defaultPlatformParser, 8 | help='Fabric related features') 9 | def fabricParser(parser): 10 | parser.add_argument('-i', '--id', type=int, default=None, action='append', 11 | help='id of the card to operate on') 12 | parser.add_argument('--parallel', action='store_true', 13 | help='run card operations in parallel') 14 | -------------------------------------------------------------------------------- /arista/cli/args/fabric/clean.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from . import fabricParser 6 | 7 | @registerParser('clean', parent=fabricParser) 8 | def cleanParser(parser): 9 | parser.add_argument('-r', '--reset', action='store_true', 10 | help='put devices in reset before cleanup') 11 | parser.add_argument('--off', action='store_true', 12 | help='power off the fabric card') 13 | -------------------------------------------------------------------------------- /arista/cli/args/fabric/diag.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function 2 | 3 | from .. import registerParser 4 | from ..diag import addDiagCommonParser 5 | from ..fabric import fabricParser 6 | 7 | @registerParser('diag', parent=fabricParser, 8 | help='dump diag information for fabrics') 9 | def diagParser(parser): 10 | addDiagCommonParser(parser) 11 | -------------------------------------------------------------------------------- /arista/cli/args/fabric/power.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerParser 3 | from . import fabricParser 4 | 5 | @registerParser('power', parent=fabricParser) 6 | def powerParser(parser): 7 | parser.add_argument('state', choices=['on', 'off'], 8 | help="change the power state of the fabric") 9 | -------------------------------------------------------------------------------- /arista/cli/args/fabric/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..common import addPriorityArgs 6 | from . import fabricParser 7 | 8 | @registerParser('setup', parent=fabricParser) 9 | def setupParser(parser): 10 | addPriorityArgs(parser) 11 | parser.add_argument('--on', action='store_true', 12 | help='turn on fabric card') 13 | parser.add_argument('--powerCycleIfOn', action='store_true', 14 | help='power cycle the fabric if already on') 15 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..default import defaultPlatformParser 6 | 7 | @registerParser('linecard', parent=defaultPlatformParser, 8 | help='Linecard related features') 9 | def linecardParser(parser): 10 | parser.add_argument('-i', '--id', type=int, default=None, action='append', 11 | help='id of the card to operate on') 12 | parser.add_argument('--parallel', action='store_true', 13 | help='run card operations in parallel') 14 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/clean.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from . import linecardParser 6 | 7 | @registerParser('clean', parent=linecardParser) 8 | def cleanParser(parser): 9 | parser.add_argument('-r', '--reset', action='store_true', 10 | help='put devices in reset before cleanup') 11 | parser.add_argument('--off', action='store_true', 12 | help='power off the fabric card') 13 | parser.add_argument('--lcpu', action='store_true', default=None, 14 | help='clean linecard cpu mode when possible') 15 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..diag import addDiagCommonParser 6 | from ..linecard import linecardParser 7 | 8 | @registerParser('diag', parent=linecardParser, 9 | help='dump diag information for linecards') 10 | def diagParser(parser): 11 | addDiagCommonParser(parser) 12 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/power.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerParser 3 | from . import linecardParser 4 | 5 | @registerParser('power', parent=linecardParser) 6 | def powerParser(parser): 7 | parser.add_argument('state', choices=['on', 'off'], 8 | help="change the power state of the linecard") 9 | parser.add_argument('--lcpu', action='store_true', default=None, 10 | help="activate linecard cpu if any") 11 | parser.add_argument('--powerCycleIfOn', action='store_true', 12 | help='power cycle the linecard if already on') 13 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/provision.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from . import linecardParser 6 | 7 | from ....core.provision import ProvisionMode 8 | 9 | @registerParser('provision', parent=linecardParser) 10 | def provisionParser(parser): 11 | parser.add_argument('--set', type=lambda mode: ProvisionMode[mode.upper()], 12 | choices=list(ProvisionMode), help='set the provision mode') 13 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/reboot.py: -------------------------------------------------------------------------------- 1 | from .. import registerParser 2 | from . import linecardParser 3 | 4 | @registerParser('reboot', parent=linecardParser) 5 | def rebootParser(parser): 6 | parser.add_argument('--mode', default='soft', choices=['soft', 'hard'], 7 | help='reset switch ASIC if in hard mode') 8 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/reboot_cause.py: -------------------------------------------------------------------------------- 1 | from .. import registerParser 2 | from . import linecardParser 3 | 4 | @registerParser('reboot-cause', parent=linecardParser) 5 | def rebootCauseParser(parser): 6 | parser.add_argument('--process', action='store_true', 7 | help='process last reboot cause and generate report (do not use)') 8 | -------------------------------------------------------------------------------- /arista/cli/args/linecard/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..common import addPriorityArgs 6 | from . import linecardParser 7 | 8 | from ....core.provision import ProvisionMode 9 | 10 | @registerParser('setup', parent=linecardParser) 11 | def setupParser(parser): 12 | addPriorityArgs(parser) 13 | parser.add_argument('--on', action='store_true', 14 | help='turn on linecard') 15 | parser.add_argument('--lcpu', action='store_true', default=None, 16 | help='activate linecard cpu mode when possible') 17 | parser.add_argument('--provision', type=lambda mode: ProvisionMode[mode.upper()], 18 | choices=list(ProvisionMode), default=None, 19 | help='set the provision mode') 20 | parser.add_argument('--powerCycleIfOn', action='store_true', 21 | help='power cycle the linecard if already on') 22 | -------------------------------------------------------------------------------- /arista/cli/args/platform/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..default import defaultPlatformParser 6 | 7 | @registerParser('platform', parent=defaultPlatformParser, 8 | help='Platform related features') 9 | def platformParser(parser): 10 | pass 11 | -------------------------------------------------------------------------------- /arista/cli/args/platform/diag.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from .. import registerParser 5 | from ..diag import addDiagCommonParser 6 | from ..platform import platformParser 7 | 8 | @registerParser('diag', parent=platformParser, 9 | help='dump diag information for the platform') 10 | def diagParser(parser): 11 | addDiagCommonParser(parser) 12 | -------------------------------------------------------------------------------- /arista/cli/args/platforms.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | 6 | @registerParser('platforms', help='show supported platforms') 7 | def platformsParser(parser): 8 | pass 9 | -------------------------------------------------------------------------------- /arista/cli/args/reboot.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | from .default import defaultPlatformParser 6 | 7 | @registerParser('reboot', parent=defaultPlatformParser, 8 | help='perform a cold reboot for platform', 9 | description=''' 10 | Powercycle the switch by cutting power to all components. 11 | The behavior of such reboot differ from a regular CPU reset. 12 | ''') 13 | def rebootParser(parser): 14 | pass 15 | -------------------------------------------------------------------------------- /arista/cli/args/reboot_cause.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | from .default import defaultPlatformParser 6 | 7 | @registerParser('reboot-cause', parent=defaultPlatformParser, 8 | help='reload cause information', 9 | description=''' 10 | Read last reboot information from the hardware and display it. 11 | ''') 12 | def rebootCauseParser(parser): 13 | parser.add_argument('--history', action='store_true', 14 | help='print reboot causes history if it exists') 15 | parser.add_argument('--process', action='store_true', 16 | help='process last reboot cause and generate report (do not use)') 17 | -------------------------------------------------------------------------------- /arista/cli/args/reset.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | from .default import defaultPlatformParser 6 | 7 | @registerParser('reset', parent=defaultPlatformParser, 8 | help='put devices in or out reset') 9 | def resetParser(parser): 10 | parser.add_argument('device', nargs='*', 11 | help='device(s) to put in or out of reset') 12 | parser.add_argument('-t', '--toggle', action='store_true', dest='reset_toggle', 13 | help='put devices in and out of reset') 14 | parser.add_argument('-i', '--in', action='store_true', dest='reset_in', 15 | help='put devices in reset') 16 | parser.add_argument('-o', '--out', action='store_true', dest='reset_out', 17 | help='put devices out of reset') 18 | parser.add_argument('-d', '--delay', type=int, default=1, dest='reset_delay', 19 | help='time to wait between in and out in seconds') 20 | parser.add_argument('-l', '--list', action='store_true', dest='reset_list', 21 | help='list devices that support reset') 22 | -------------------------------------------------------------------------------- /arista/cli/args/setup.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | from .common import addPriorityArgs 6 | from .default import defaultPlatformParser 7 | 8 | @registerParser('setup', parent=defaultPlatformParser, 9 | help='setup drivers for this platform') 10 | def setupParser(parser): 11 | parser.add_argument('-r', '--reset', action='store_true', 12 | help='put devices out of reset after init') 13 | parser.add_argument('-d', '--debug', action='store_true', 14 | help='enable debug features for the drivers') 15 | parser.add_argument('-b', '--background', action='store_true', 16 | help='initialize slow, non-critical drivers in background') 17 | addPriorityArgs(parser) 18 | -------------------------------------------------------------------------------- /arista/cli/args/show/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerParser 3 | from ..default import defaultPlatformParser 4 | 5 | @registerParser('show', parent=defaultPlatformParser, 6 | help='Show commands') 7 | def showParser(parser): 8 | parser.add_argument('-j', '--json', action='store_true', 9 | help='output library information in json format') 10 | parser.add_argument('-p', '--pretty', action='store_true', 11 | help='generate a pretty output when applicable') 12 | -------------------------------------------------------------------------------- /arista/cli/args/show/chassis/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerParser, showParser 3 | from ...chassis import chassisParser 4 | 5 | @registerParser('chassis', parent=showParser, 6 | help='Chassis show commands') 7 | def showChassisParser(parser): 8 | chassisParser(parser) 9 | -------------------------------------------------------------------------------- /arista/cli/args/show/chassis/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showChassisParser 3 | 4 | @registerParser('eeprom', parent=showChassisParser, 5 | help='Show chassis eeprom content') 6 | def showChassisEepromParser(_parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/chassis/summary.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import registerParser 3 | from . import showChassisParser 4 | 5 | @registerParser('summary', parent=showChassisParser, 6 | help='Show information about the chassis') 7 | def chassisSummaryParser(parser): 8 | pass 9 | -------------------------------------------------------------------------------- /arista/cli/args/show/fabric/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ... import registerParser 3 | from ...fabric import fabricParser 4 | from ...show import showParser 5 | 6 | @registerParser('fabric', parent=showParser, 7 | help='Fabric show commands') 8 | def showFabricParser(parser): 9 | fabricParser(parser) 10 | -------------------------------------------------------------------------------- /arista/cli/args/show/fabric/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showFabricParser 3 | 4 | @registerParser('eeprom', parent=showFabricParser, 5 | help='Show fabric eeprom content') 6 | def showFabricEepromParser(_parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/fabric/environment.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showFabricParser 3 | 4 | @registerParser('environment', parent=showFabricParser, 5 | help='Show environmental info') 6 | def environmentParser(parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/fabric/status.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showFabricParser 3 | 4 | @registerParser('status', parent=showFabricParser, 5 | help='Show fabric status') 6 | def statusParser(parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/linecard/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ... import registerParser 3 | from ...linecard import linecardParser 4 | from ...show import showParser 5 | 6 | @registerParser('linecard', parent=showParser, 7 | help='Linecard show commands') 8 | def showLinecardParser(parser): 9 | linecardParser(parser) 10 | -------------------------------------------------------------------------------- /arista/cli/args/show/linecard/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showLinecardParser 3 | 4 | @registerParser('eeprom', parent=showLinecardParser, 5 | help='Show linecard eeprom content') 6 | def showLinecardEepromParser(_parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/linecard/environment.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showLinecardParser 3 | 4 | @registerParser('environment', parent=showLinecardParser, 5 | help='Show environmental info') 6 | def environmentParser(parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/linecard/reboot_cause.py: -------------------------------------------------------------------------------- 1 | from .. import registerParser 2 | from . import showLinecardParser 3 | 4 | @registerParser('reboot-cause', parent=showLinecardParser, 5 | help='Show reboot cause info') 6 | def showRebootCauseParser(parser): 7 | parser.add_argument('-a', '--all', action='store_true', 8 | help='print reboot cause info for all attached chips') 9 | parser.add_argument('-H', '--history', action='store_true', 10 | help='print reboot causes history if it exists') 11 | -------------------------------------------------------------------------------- /arista/cli/args/show/linecard/status.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showLinecardParser 3 | 4 | @registerParser('status', parent=showLinecardParser, 5 | help='Show linecard status') 6 | def statusParser(parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/platform/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ... import registerParser 3 | from ...default import defaultPlatformParser 4 | from ...show import showParser 5 | 6 | @registerParser('platform', parent=showParser, 7 | help='Platform show commands') 8 | def showPlatformParser(parser): 9 | defaultPlatformParser(parser) 10 | -------------------------------------------------------------------------------- /arista/cli/args/show/platform/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showPlatformParser 3 | 4 | @registerParser('eeprom', parent=showPlatformParser, 5 | help='Show platform eeprom content') 6 | def showPlatformEepromParser(_parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/platform/environment.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showPlatformParser 3 | 4 | @registerParser('environment', parent=showPlatformParser, 5 | help='Show environmental info') 6 | def environmentParser(parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/platform/power.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showPlatformParser 3 | 4 | @registerParser('power', parent=showPlatformParser, 5 | help='Show power info') 6 | def powerParser(parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/platform/reboot_cause.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showPlatformParser 3 | 4 | @registerParser('reboot-cause', parent=showPlatformParser, 5 | help='Show reboot cause info') 6 | def rebootCauseParser(parser): 7 | parser.add_argument('-a', '--all', action='store_true') 8 | parser.add_argument('-H', '--history', action='store_true') 9 | -------------------------------------------------------------------------------- /arista/cli/args/show/platform/xcvr.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showPlatformParser 3 | 4 | @registerParser('xcvr', parent=showPlatformParser, 5 | help='Show transceiver info') 6 | def xcvrParser(parser): 7 | pass 8 | -------------------------------------------------------------------------------- /arista/cli/args/show/supported.py: -------------------------------------------------------------------------------- 1 | 2 | from . import registerParser, showParser 3 | 4 | @registerParser('supported', parent=showParser, help='show supported platforms') 5 | def supportedParser(parser): 6 | pass 7 | -------------------------------------------------------------------------------- /arista/cli/args/syseeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | 6 | @registerParser('syseeprom', help='show system eeprom content') 7 | def syseepromParser(parser): 8 | pass 9 | -------------------------------------------------------------------------------- /arista/cli/args/watchdog.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from . import registerParser 5 | from .default import defaultPlatformParser 6 | 7 | @registerParser('watchdog', parent=defaultPlatformParser, 8 | help='configure the hardware watchdog') 9 | def watchdogParser(parser): 10 | parser = parser.add_mutually_exclusive_group(required=True) 11 | parser.add_argument('--status', action='store_true', dest='watchdog_status', 12 | help='print the hardware watchdog status') 13 | parser.add_argument('--stop', action='store_true', dest='watchdog_stop', 14 | help='stop the hardware watchdog') 15 | parser.add_argument('--arm', type=int, nargs='?', dest='watchdog_timeout', 16 | const=300, help='arm the hardware watchdog for X seconds before it triggers') 17 | -------------------------------------------------------------------------------- /arista/cli/exception.py: -------------------------------------------------------------------------------- 1 | 2 | class ActionError(Exception): 3 | def __init__(self, msg, code=1): 4 | self.code = code 5 | self.msg = msg 6 | 7 | def __str__(self): 8 | return '%s: %s (code %d)' % (self.__class__.__name__, self.msg, self.code) 9 | 10 | class ActionComplete(ActionError): 11 | def __init__(self, msg='action completed early', code=0): 12 | super().__init__(msg=msg, code=code) 13 | -------------------------------------------------------------------------------- /arista/cli/fork.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..core.log import getLogger, getLoggerManager 4 | 5 | from .exception import ActionComplete 6 | 7 | logging = getLogger(__name__) 8 | 9 | def processIterParentWait(collection): 10 | """The collection needs to be an iterable""" 11 | 12 | pids = [] 13 | 14 | for item in collection: 15 | pid = os.fork() 16 | if pid == 0: 17 | logging.debug('[child %s] starting for %s...', os.getpid(), item) 18 | getLoggerManager().setPrefix('%s: ' % item) 19 | # NOTE: once in the fork, yield the item and stop the iteration 20 | # it means that each item in the for loop will be executed in a 21 | # different process. 22 | yield item 23 | return 24 | 25 | pids.append(pid) 26 | 27 | # wait for processes to finish 28 | for pid in pids: 29 | logging.debug('[parent] waiting for child %d', pid) 30 | os.waitpid(pid, 0) 31 | 32 | logging.debug('[parent] all children completed') 33 | 34 | # the main process doesn't do anything 35 | raise ActionComplete 36 | -------------------------------------------------------------------------------- /arista/cli/show/card.py: -------------------------------------------------------------------------------- 1 | 2 | from . import Renderer 3 | 4 | from ...core.linecard import Linecard 5 | 6 | def tryGet(func, default): 7 | try: 8 | return func() 9 | except Exception: # pylint: disable=broad-except 10 | return default 11 | 12 | class ShowCardStatus(Renderer): 13 | 14 | NAME = 'status' 15 | 16 | def getData(self, show): 17 | data = [] 18 | for card, metadata in show.inventories: 19 | tmp = { 20 | 'name': str(card), 21 | 'slotId': card.getSlotId(), 22 | 'sku': card.slot.getEeprom().get('SKU'), 23 | 'sid': card.slot.getEeprom().get('SID'), 24 | 'present': tryGet(card.getPresence, False), 25 | 'on': bool(tryGet(card.poweredOn, False)), 26 | } 27 | if isinstance(card, Linecard): 28 | tmp.update({ 29 | 'hasCpu': tryGet(card.hasCpuModule, False), 30 | }) 31 | data.append(tmp) 32 | return data 33 | 34 | def renderText(self, show): 35 | data = self.data(show) 36 | for card in data: 37 | print(card['name']) 38 | for k, v in card.items(): 39 | if k != 'name': 40 | print(' %s: %s' % (k, v)) 41 | -------------------------------------------------------------------------------- /arista/cli/show/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | from . import Renderer 3 | 4 | class ShowEeprom(Renderer): 5 | 6 | NAME = 'eeprom' 7 | 8 | def getData(self, show): 9 | ret = [] 10 | for inventory, metadata in show.inventories: 11 | inventory.update(metadata) 12 | ret += [inventory] 13 | return ret 14 | 15 | def renderText(self, show): 16 | data = self.data(show) 17 | 18 | t = ['\n'.join(['%s: %s' % (k, v) for k, v in d.items()]) for d in data] 19 | print('\n\n'.join(t)) 20 | -------------------------------------------------------------------------------- /arista/cli/show/xcvr.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.diag import DiagContext 3 | 4 | from . import Renderer, Table, Col 5 | 6 | class ShowXcvr(Renderer): 7 | 8 | NAME = 'xcvr' 9 | 10 | def getData(self, show): 11 | ctx = DiagContext() 12 | data = [] 13 | for inventory, _ in show.inventories: 14 | for name, xcvr in inventory.getXcvrSlots().items(): 15 | data.append(xcvr.__diag__(ctx)) 16 | return data 17 | 18 | def renderText(self, show): 19 | data = self.data(show) 20 | 21 | Table([ 22 | Col('Id', 'id', 3), 23 | Col('Type', 'xcvr.type', 7), 24 | Col('Present', 'present', 7), 25 | Col('LpMode', 'lpmode', 6), 26 | Col('Reset', 'reset.value', 6), 27 | Col('TxDisable', 'txdisable', 9), 28 | Col('TxFault', 'txfault', 7), 29 | Col('RxLos', 'rxlos', 5), 30 | Col('Addr', 'xcvr.addr', 7), 31 | ]).render(data) 32 | -------------------------------------------------------------------------------- /arista/cli/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/cli/tests/__init__.py -------------------------------------------------------------------------------- /arista/components/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/__init__.py -------------------------------------------------------------------------------- /arista/components/asic/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/asic/__init__.py -------------------------------------------------------------------------------- /arista/components/asic/bfn/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.asic import SwitchChip 3 | 4 | class BarefootChip(SwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/bfn/tofino.py: -------------------------------------------------------------------------------- 1 | 2 | from . import BarefootChip 3 | 4 | class Tofino(BarefootChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/bfn/tofino2.py: -------------------------------------------------------------------------------- 1 | 2 | from . import BarefootChip 3 | 4 | class Tofino2(BarefootChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/dnx/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.asic import SwitchChip 3 | 4 | class DnxSwitchChip(SwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/dnx/jericho2.py: -------------------------------------------------------------------------------- 1 | 2 | from . import DnxSwitchChip 3 | 4 | class Jericho2(DnxSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/dnx/jericho2c.py: -------------------------------------------------------------------------------- 1 | 2 | from . import DnxSwitchChip 3 | 4 | class Jericho2cPlus(DnxSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/dnx/ramon.py: -------------------------------------------------------------------------------- 1 | 2 | from . import DnxSwitchChip 3 | 4 | class Ramon(DnxSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.asic import SwitchChip 3 | 4 | class XgsSwitchChip(SwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/tomahawk.py: -------------------------------------------------------------------------------- 1 | 2 | from . import XgsSwitchChip 3 | 4 | class Tomahawk(XgsSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/tomahawk2.py: -------------------------------------------------------------------------------- 1 | 2 | from . import XgsSwitchChip 3 | 4 | class Tomahawk2(XgsSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/tomahawk3.py: -------------------------------------------------------------------------------- 1 | 2 | from . import XgsSwitchChip 3 | 4 | class Tomahawk3(XgsSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/tomahawk4.py: -------------------------------------------------------------------------------- 1 | 2 | from . import XgsSwitchChip 3 | 4 | class Tomahawk4(XgsSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/tomahawk5.py: -------------------------------------------------------------------------------- 1 | 2 | from . import XgsSwitchChip 3 | 4 | class Tomahawk5(XgsSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/trident2.py: -------------------------------------------------------------------------------- 1 | 2 | from . import XgsSwitchChip 3 | 4 | class Trident2(XgsSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/trident3.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.quirk import Quirk 3 | from ....core.register import RegisterMap, Register, RegBitRange 4 | 5 | from ....libs.wait import waitFor 6 | 7 | from ...vrm import VrmDetector 8 | 9 | from . import XgsSwitchChip 10 | 11 | class Trident3(XgsSwitchChip): 12 | pass 13 | 14 | class Trident3X2RegMap(RegisterMap): 15 | DMU_PCU_OTP_CONFIG_9 = Register(0x6c, 16 | RegBitRange(21, 24, name='avsValue'), 17 | name='configReg', 18 | ) 19 | 20 | class Trident3X2(Trident3): 21 | REGISTER_CLS = Trident3X2RegMap 22 | 23 | class AvsQuirk(Quirk): 24 | 25 | DELAYED = True 26 | 27 | ASIC_TO_MILLIVOLT = { 28 | 0x1: 800, 29 | 0x2: 825, 30 | 0x4: 850, 31 | 0x8: 875, 32 | } 33 | 34 | def __init__(self, vrm): 35 | self.vrm_ = vrm 36 | 37 | @property 38 | def vrm(self): 39 | if isinstance(self.vrm_, VrmDetector): 40 | return self.vrm_.vrm 41 | return self.vrm 42 | 43 | def waitAsicRegisterReady(self, asic): 44 | waitFor( 45 | lambda: asic.driver.regs.configReg() != 0xffffffff, 46 | description='Asic config register ready', 47 | ) 48 | 49 | def run(self, component): 50 | self.waitAsicRegisterReady(component) 51 | value = component.driver.regs.avsValue() 52 | vout = self.ASIC_TO_MILLIVOLT.get(value) 53 | if vout is not None: 54 | self.vrm.setVoutValue(vout) 55 | -------------------------------------------------------------------------------- /arista/components/asic/xgs/trident4.py: -------------------------------------------------------------------------------- 1 | 2 | from . import XgsSwitchChip 3 | 4 | class Trident4(XgsSwitchChip): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/cpu/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/cpu/__init__.py -------------------------------------------------------------------------------- /arista/components/cpu/amd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/cpu/amd/__init__.py -------------------------------------------------------------------------------- /arista/components/cpu/amd/designware.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.types import I2cBus 3 | 4 | class DesignWareI2cBus(I2cBus): 5 | def __init__(self, bus): 6 | # NOTE: this i2c adapters don't have a unique naming 7 | # therefore assume probe order but not contiguous kernel bus ids 8 | name = 'Synopsys DesignWare I2C adapter' 9 | super().__init__(name, idx=bus) 10 | -------------------------------------------------------------------------------- /arista/components/cpu/amd/k10temp.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.component import Priority 3 | from ....core.component.pci import PciComponent 4 | 5 | from ....drivers.k10temp import K10TempKernelDriver 6 | 7 | class K10Temp(PciComponent): 8 | DRIVER = K10TempKernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/cpu/amd/piix.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.types import I2cBus 3 | 4 | class PiixI2cBus(I2cBus): 5 | def __init__(self, port, addr): 6 | name = 'SMBus PIIX4 adapter port %d at %04x' % (port, addr) 7 | super().__init__(name) 8 | -------------------------------------------------------------------------------- /arista/components/cpu/amd/sbtsi.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.component.i2c import I2cComponent 3 | from ....drivers.sbtsi import SbTsiUserDriver 4 | 5 | class SbTsi(I2cComponent): 6 | DRIVER = SbTsiUserDriver 7 | -------------------------------------------------------------------------------- /arista/components/cpu/cormorant.py: -------------------------------------------------------------------------------- 1 | 2 | from ..cpld import SysCpld, SysCpldCommonRegistersV2 3 | 4 | class CormorantCpldRegisters(SysCpldCommonRegistersV2): 5 | pass 6 | 7 | class CormorantSysCpld(SysCpld): 8 | REGISTER_CLS = CormorantCpldRegisters 9 | -------------------------------------------------------------------------------- /arista/components/cpu/intel/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/cpu/intel/__init__.py -------------------------------------------------------------------------------- /arista/components/cpu/intel/coretemp.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.component import Priority 3 | from ....core.component.pci import PciComponent 4 | 5 | from ....drivers.coretemp import CoretempKernelDriver 6 | 7 | class Coretemp(PciComponent): 8 | DRIVER = CoretempKernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/cpu/intel/pch.py: -------------------------------------------------------------------------------- 1 | 2 | from ....core.component import Priority 3 | from ....core.component.pci import PciComponent 4 | 5 | from ....drivers.pch import PchTempKernelDriver 6 | 7 | class PchTemp(PciComponent): 8 | DRIVER = PchTempKernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/cpu/lorikeet.py: -------------------------------------------------------------------------------- 1 | 2 | from ..cpld import SysCpld, SysCpldCommonRegistersV2 3 | from ..scd import ScdReloadCauseRegisters 4 | 5 | class LorikeetCpldRegisters(SysCpldCommonRegistersV2): 6 | pass 7 | 8 | class LorikeetSysCpld(SysCpld): 9 | REGISTER_CLS = LorikeetCpldRegisters 10 | 11 | class LorikeetPrimeScdReloadCauseRegisters(ScdReloadCauseRegisters): 12 | pass 13 | -------------------------------------------------------------------------------- /arista/components/cpu/raven.py: -------------------------------------------------------------------------------- 1 | from ...core.component import Priority 2 | from ...core.component.component import Component 3 | 4 | from ...drivers.raven import RavenFanKernelDriver 5 | 6 | class RavenFanComplex(Component): 7 | PRIORITY = Priority.THERMAL 8 | DRIVER = RavenFanKernelDriver 9 | -------------------------------------------------------------------------------- /arista/components/cpu/redstart.py: -------------------------------------------------------------------------------- 1 | 2 | from ..cpld import SysCpld 3 | from ..scd import ScdReloadCauseRegisters 4 | 5 | from .shearwater import ShearwaterSysCpldRegisters 6 | 7 | class RedstartSysCpld(SysCpld): 8 | REGISTER_CLS = ShearwaterSysCpldRegisters 9 | 10 | class RedstartReloadCauseRegisters(ScdReloadCauseRegisters): 11 | pass 12 | -------------------------------------------------------------------------------- /arista/components/cpu/rook.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.component import Priority 3 | from ...core.component.i2c import I2cComponent 4 | from ...core.register import Register, RegBitField 5 | 6 | from ...drivers.rook import ( 7 | LaFanCpldKernelDriver, 8 | TehamaFanCpldKernelDriver, 9 | RookStatusLedKernelDriver, 10 | ) 11 | 12 | from ..cpld import SysCpld, SysCpldCommonRegistersV2 13 | 14 | class RookCpldRegisters(SysCpldCommonRegistersV2): 15 | pass 16 | 17 | class RookSysCpld(SysCpld): 18 | REGISTER_CLS = RookCpldRegisters 19 | 20 | class RookStatusLeds(I2cComponent): 21 | DRIVER = RookStatusLedKernelDriver 22 | PRIORITY = Priority.LED 23 | 24 | class RookFanCpld(I2cComponent): 25 | PRIORITY = Priority.COOLING 26 | FAN_COUNT = 0 27 | 28 | class LaFanCpld(RookFanCpld): 29 | DRIVER = LaFanCpldKernelDriver 30 | FAN_COUNT = 4 31 | 32 | class TehamaFanCpld(RookFanCpld): 33 | DRIVER = TehamaFanCpldKernelDriver 34 | FAN_COUNT = 5 35 | -------------------------------------------------------------------------------- /arista/components/cpu/shearwater.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.register import Register, RegBitField 3 | 4 | from ..cpld import SysCpld, SysCpldCommonRegisters 5 | from ..scd import ScdReloadCauseRegisters 6 | 7 | class ShearwaterSysCpldRegisters(SysCpldCommonRegisters): 8 | PWR_CTRL_STS = Register(0x05, 9 | RegBitField(7, 'pwrCtrl7', ro=False), 10 | RegBitField(6, 'pwrCtrl6', ro=False), 11 | RegBitField(5, 'pwrCtrl5', ro=False), 12 | RegBitField(4, 'pwrCtrl4', ro=False), 13 | RegBitField(3, 'pwrCtrl3', ro=False), 14 | RegBitField(2, 'pwrCtrl2', ro=False), 15 | RegBitField(1, 'pwrCtrl1', ro=False), 16 | RegBitField(0, 'switchCardPowerGood'), 17 | ) 18 | SCD_CTRL_STS = Register(0x0A, 19 | RegBitField(6, 'scdInit', flip=True), 20 | RegBitField(5, 'scdReset', ro=False), 21 | RegBitField(4, 'scdHold', ro=False), 22 | RegBitField(3, 'scdConfig', ro=False), 23 | RegBitField(1, 'scdInitDone'), 24 | RegBitField(0, 'scdConfDone'), 25 | ) 26 | # TODO crc seu 27 | 28 | class ShearwaterSysCpld(SysCpld): 29 | REGISTER_CLS = ShearwaterSysCpldRegisters 30 | 31 | class ShearwaterReloadCauseRegisters(ScdReloadCauseRegisters): 32 | pass 33 | -------------------------------------------------------------------------------- /arista/components/denali/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/denali/__init__.py -------------------------------------------------------------------------------- /arista/components/denali/chassis.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.modular import Modular 3 | 4 | class DenaliChassis(Modular): 5 | NUM_SUPERVISORS = 2 6 | -------------------------------------------------------------------------------- /arista/components/denali/desc.py: -------------------------------------------------------------------------------- 1 | 2 | class DenaliAsicDesc(object): 3 | def __init__(self, cls=None, asicId=None, rstIdx=None): 4 | self.cls = cls 5 | self.asicId = asicId 6 | self.rstIdx = rstIdx or asicId 7 | -------------------------------------------------------------------------------- /arista/components/denali/psu.py: -------------------------------------------------------------------------------- 1 | 2 | class DenaliPsuSlotDesc(object): 3 | def __init__(self, psuId, bank, slot, bus, addr): 4 | self.psuId = psuId 5 | self.bank = bank 6 | self.slot = slot 7 | self.bus = bus 8 | self.addr = addr 9 | -------------------------------------------------------------------------------- /arista/components/denali/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/denali/tests/__init__.py -------------------------------------------------------------------------------- /arista/components/dpm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/dpm/__init__.py -------------------------------------------------------------------------------- /arista/components/ds125br.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.ds125br import Ds125BrDevDriver 6 | 7 | class Ds125Br(I2cComponent): 8 | DRIVER = Ds125BrDevDriver 9 | PRIORITY = Priority.DEFAULT 10 | -------------------------------------------------------------------------------- /arista/components/lm73.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.lm73 import Lm73KernelDriver 6 | 7 | class Lm73(I2cComponent): 8 | DRIVER = Lm73KernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/lm75.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.lm75 import Lm75KernelDriver, Tmp75KernelDriver 6 | 7 | class Lm75(I2cComponent): 8 | DRIVER = Lm75KernelDriver 9 | PRIORITY = Priority.THERMAL 10 | 11 | class Tmp75(Lm75): 12 | DRIVER = Tmp75KernelDriver 13 | -------------------------------------------------------------------------------- /arista/components/max31790.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.max31790 import Max31790KernelDriver 6 | 7 | class Max31790(I2cComponent): 8 | PRIORITY = Priority.THERMAL 9 | DRIVER = Max31790KernelDriver 10 | -------------------------------------------------------------------------------- /arista/components/max6581.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.max6581 import Max6581KernelDriver 6 | 7 | class Max6581(I2cComponent): 8 | DRIVER = Max6581KernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/max6658.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.max6658 import Max6658KernelDriver 6 | 7 | class Max6658(I2cComponent): 8 | DRIVER = Max6658KernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/max6697.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.max6697 import Max6697KernelDriver 6 | 7 | class Max6697(I2cComponent): 8 | DRIVER = Max6697KernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/microsemi.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.pci import PciSwitch, DownstreamPciPort 4 | 5 | from ..drivers.microsemi import MicrosemiDriver 6 | from ..drivers.pci import PciSwitchPortDriver 7 | 8 | class MicrosemiPortDesc(object): 9 | def __init__(self, port, dsp, partition): 10 | self.port = port 11 | self.dsp = dsp 12 | self.partition = partition 13 | 14 | class MicrosemiPort(DownstreamPciPort): 15 | 16 | DRIVER = PciSwitchPortDriver 17 | PRIORITY = Priority.DEFAULT 18 | 19 | def __init__(self, port=0, desc=None, **kwargs): 20 | super(MicrosemiPort, self).__init__(port=port, **kwargs) 21 | self.desc = desc 22 | 23 | def enable(self): 24 | self.driver.enable() 25 | 26 | def disable(self): 27 | self.driver.disable() 28 | 29 | def bind(self): 30 | return self.parent.bind(self) 31 | 32 | def unbind(self): 33 | return self.parent.unbind(self) 34 | 35 | class Microsemi(PciSwitch): 36 | 37 | DRIVER = MicrosemiDriver 38 | PRIORITY = Priority.DEFAULT 39 | 40 | DOWNSTREAM_PORT_CLS = MicrosemiPort 41 | 42 | def addPciPort(self, desc=None, **kwargs): 43 | return self.downstreamPort(port=desc.port, device=desc.dsp - 1, desc=desc, **kwargs) 44 | 45 | def bind(self, port): 46 | desc = port.desc 47 | return self.driver.bind(desc.port, desc.dsp, desc.partition) 48 | 49 | def unbind(self, port, flags=0x2): 50 | desc = port.desc 51 | return self.driver.unbind(desc.dsp, desc.partition, flags=flags) 52 | -------------------------------------------------------------------------------- /arista/components/minke.py: -------------------------------------------------------------------------------- 1 | from ..components.lm75 import Tmp75 2 | 3 | from ..core.component.i2c import I2cComponent 4 | from ..core.component import Priority 5 | from ..core.fan import FanSlot 6 | 7 | from ..descs.fan import FanDesc, FanPosition 8 | from ..descs.led import LedDesc, LedColor 9 | from ..descs.sensor import Position, SensorDesc 10 | 11 | from ..drivers.minke import MinkeFanCpldKernelDriver 12 | 13 | from .eeprom import At24C32 14 | 15 | class MinkeFanCpld(I2cComponent): 16 | DRIVER = MinkeFanCpldKernelDriver 17 | PRIORITY = Priority.COOLING 18 | 19 | class Minke: 20 | 21 | FAN_SLOTS = 3 22 | FAN_COUNT = 6 23 | 24 | def __init__(self, parent, bus): 25 | parent.newComponent(Tmp75, addr=bus.i2cAddr(0x48), sensors=[ 26 | SensorDesc(diode=0, name='Outlet', position=Position.OUTLET, 27 | target=65, overheat=80, critical=95), 28 | ]) 29 | self.eeprom = parent.newComponent(At24C32, addr=bus.i2cAddr(0x50)) 30 | 31 | self.cpld = parent.newComponent(MinkeFanCpld, addr=bus.i2cAddr(0x60)) 32 | 33 | for slotId in range(1, self.FAN_SLOTS + 1): 34 | parent.newComponent( 35 | FanSlot, 36 | slotId=slotId, 37 | led=self.cpld.addFanLed(LedDesc( 38 | name='fan_slot%d' % slotId, 39 | colors=[LedColor.RED, LedColor.AMBER, LedColor.GREEN, 40 | LedColor.BLUE, LedColor.OFF], 41 | )), 42 | fans=[self.cpld.addFan(desc) for desc in [ 43 | FanDesc(fanId=slotId * 2 - 1, position=FanPosition.INLET), 44 | FanDesc(fanId=slotId * 2, position=FanPosition.INLET), 45 | ]], 46 | ) 47 | -------------------------------------------------------------------------------- /arista/components/pali.py: -------------------------------------------------------------------------------- 1 | from ..components.lm75 import Tmp75 2 | 3 | from ..core.component.i2c import I2cComponent 4 | from ..core.component import Priority 5 | from ..core.fan import FanSlot 6 | from ..core.utils import incrange 7 | 8 | from ..descs.fan import FanDesc, FanPosition 9 | from ..descs.led import LedDesc, LedColor 10 | from ..descs.sensor import Position, SensorDesc 11 | 12 | from ..drivers.pali import Pali2FanCpldKernelDriver 13 | 14 | from .eeprom import At24C32 15 | 16 | class Pali2FanCpld(I2cComponent): 17 | DRIVER = Pali2FanCpldKernelDriver 18 | PRIORITY = Priority.COOLING 19 | 20 | class Pali2: 21 | 22 | FAN_COUNT = 4 23 | 24 | def __init__(self, parent, bus): 25 | parent.newComponent(Tmp75, addr=bus.i2cAddr(0x48), sensors=[ 26 | SensorDesc(diode=0, name='Outlet', position=Position.OUTLET, 27 | target=65, overheat=80, critical=95), 28 | ]) 29 | 30 | self.eeprom = parent.newComponent(At24C32, addr=bus.i2cAddr(0x50)) 31 | 32 | self.cpld = parent.newComponent(Pali2FanCpld, addr=bus.i2cAddr(0x60)) 33 | 34 | for slotId in incrange(1, self.FAN_COUNT): 35 | fan = self.cpld.addFan(FanDesc(fanId=slotId, position=FanPosition.INLET)) 36 | led = self.cpld.addFanLed(LedDesc(name='fan%d' % slotId, 37 | colors=[LedColor.RED, LedColor.GREEN, LedColor.OFF])) 38 | parent.newComponent(FanSlot, slotId=slotId, led=led, fans=[fan]) 39 | -------------------------------------------------------------------------------- /arista/components/pca9541.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component.i2c import I2cComponent 3 | from ..core.types import I2cAddr 4 | 5 | from ..drivers.pca9541 import Pca9541I2cDevDriver, Pca9541KernelDriver 6 | 7 | class PcaI2cAddr(I2cAddr): 8 | def __init__(self, pca, addr): 9 | super(PcaI2cAddr, self).__init__(None, addr) 10 | self.pca_ = pca 11 | 12 | @property 13 | def bus(self): 14 | return self.pca_.getBus() 15 | 16 | class Pca9541(I2cComponent): 17 | 18 | DRIVER = Pca9541KernelDriver 19 | 20 | def __init__(self, addr, driverMode='user', **kwargs): 21 | # TODO: fix driver declaration with DriverSelector 22 | driverCls = Pca9541I2cDevDriver if driverMode == 'user' else \ 23 | Pca9541KernelDriver 24 | super(Pca9541, self).__init__(addr=addr, driverCls=driverCls, **kwargs) 25 | 26 | def takeOwnership(self): 27 | return self.driver.takeOwnership() 28 | 29 | def ping(self): 30 | return self.driver.ping() 31 | 32 | def getBus(self): 33 | return self.driver.getBus() 34 | 35 | def i2cAddr(self, addr): 36 | return PcaI2cAddr(self, addr) 37 | -------------------------------------------------------------------------------- /arista/components/pca9555.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.pca9555 import Pca9555I2cDevDriver 6 | 7 | class Pca9555(I2cComponent): 8 | 9 | DRIVER = Pca9555I2cDevDriver 10 | PRIORITY = Priority.DEFAULT 11 | 12 | def resetConfig(self): 13 | self.driver.reset() 14 | 15 | def addGpio(self, name): 16 | return self.inventory.addGpio(self.driver.getGpio(name)) 17 | 18 | def addGpioLed(self, name, **kwargs): 19 | return self.inventory.addLed(self.driver.getGpioLed(name, **kwargs)) 20 | 21 | def addRedGreenGpioLed(self, name, rname, gname, **kwargs): 22 | return self.inventory.addLed( 23 | self.driver.getRedGreenGpioLed(name, rname, gname, **kwargs)) 24 | 25 | def __getattr__(self, key): 26 | return getattr(self.driver.regs, key) 27 | -------------------------------------------------------------------------------- /arista/components/phy/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ...inventory.phy import Phy 3 | 4 | class PhyImpl(Phy): 5 | def __init__(self, phyId, reset=None): 6 | self.id = phyId 7 | self.reset = reset 8 | 9 | def getReset(self): 10 | return self.reset 11 | 12 | class MdioPhy(PhyImpl): 13 | def __init__(self, phyId, mdios, reset=None): 14 | super(MdioPhy, self).__init__(phyId, reset=reset) 15 | self.mdios = mdios 16 | 17 | def getMdios(self): 18 | return self.mdios 19 | -------------------------------------------------------------------------------- /arista/components/phy/b52.py: -------------------------------------------------------------------------------- 1 | 2 | from ..phy import MdioPhy 3 | 4 | class B52(MdioPhy): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/phy/babbage.py: -------------------------------------------------------------------------------- 1 | 2 | from ..phy import MdioPhy 3 | 4 | class Babbage(MdioPhy): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/phy/babbagelp.py: -------------------------------------------------------------------------------- 1 | 2 | from ..phy import MdioPhy 3 | 4 | class BabbageLP(MdioPhy): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/phy/broncos.py: -------------------------------------------------------------------------------- 1 | 2 | from ..phy import MdioPhy 3 | 4 | class Broncos(MdioPhy): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/components/psu/__init__.py: -------------------------------------------------------------------------------- 1 | from ...core.component import Priority 2 | from ...core.component.i2c import I2cComponent 3 | 4 | from ...drivers.pmbus import PmbusKernelDriver 5 | 6 | class PmbusPsu(I2cComponent): 7 | DRIVER = PmbusKernelDriver 8 | PRIORITY = Priority.POWER 9 | -------------------------------------------------------------------------------- /arista/components/psu/dcdc.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Arista Networks, Inc. All rights reserved. 2 | # Arista Networks, Inc. Confidential and Proprietary. 3 | 4 | from ...core.psu import PsuModel, PsuIdent 5 | 6 | from . import PmbusPsu 7 | from .helper import psuDescHelper, Position 8 | 9 | class FlexBmr313(PsuModel): 10 | CAPACITY = 1000 11 | MANUFACTURER = ''.join(chr(c) for c in [0x1a, 0x0]) 12 | PMBUS_ADDR = 0x10 13 | PMBUS_CLS = PmbusPsu 14 | IDENTIFIERS = [ 15 | PsuIdent(''.join(chr(c) for c in [0x60, 0x0]), 'BMR313-48V-12V', None), 16 | ] 17 | DESCRIPTION = psuDescHelper( 18 | sensors=[ 19 | ('internal', Position.OTHER, 100, 120, 130), 20 | ], 21 | hasFans=False, 22 | outputMinVoltage=11.25, 23 | outputMaxVoltage=13.39 24 | ) 25 | 26 | class FlexBmr313Addr18(FlexBmr313): 27 | PMBUS_ADDR = 0x12 28 | 29 | class DeltaU50su(FlexBmr313): 30 | MANUFACTURER = 'DELTA' + chr(0x0) 31 | IDENTIFIERS = [ 32 | PsuIdent('U50SU4P180PMDAF', 'U50SU-48V-12V', None), 33 | ] 34 | 35 | class DeltaU50suAddr18(DeltaU50su): 36 | PMBUS_ADDR = 0x12 37 | -------------------------------------------------------------------------------- /arista/components/psu/ds460.py: -------------------------------------------------------------------------------- 1 | 2 | from ...drivers.ds460 import Ds460KernelDriver 3 | 4 | from . import PmbusPsu 5 | 6 | class Ds460(PmbusPsu): 7 | DRIVER = Ds460KernelDriver 8 | -------------------------------------------------------------------------------- /arista/components/psu/emerson.py: -------------------------------------------------------------------------------- 1 | from ...core.cooling import Airflow 2 | from ...core.psu import PsuModel, PsuIdent 3 | 4 | from . import PmbusPsu 5 | from .helper import psuDescHelper, Position 6 | 7 | class EmersonPsu(PsuModel): 8 | MANUFACTURER = 'emerson' 9 | PMBUS_ADDR = 0x58 10 | 11 | PMBUS_CLS = PmbusPsu 12 | 13 | class DS750PED(EmersonPsu): 14 | CAPACITY = 750 15 | DESCRIPTION = psuDescHelper( 16 | sensors=[ 17 | ('hotspot', Position.OTHER, 85, 100, 105), 18 | ('ambiant', Position.OTHER, 55, 70, 75), 19 | ], 20 | ) 21 | IDENTIFIERS = [ 22 | PsuIdent('DS750PED-3', 'PWR-745AC-F', Airflow.EXHAUST), 23 | PsuIdent('DS750PED-3-001', 'PWR-745AC-R', Airflow.INTAKE), 24 | PsuIdent('DS750PED-3-402', 'PWR-745AC-R', Airflow.INTAKE), 25 | PsuIdent('DS750PED-3-403', 'PWR-745AC-F', Airflow.EXHAUST), 26 | ] 27 | -------------------------------------------------------------------------------- /arista/components/psu/fixed.py: -------------------------------------------------------------------------------- 1 | from ...core.cooling import Airflow 2 | from ...core.psu import PsuModel, PsuIdent 3 | 4 | from ...descs.psu import PsuDesc 5 | 6 | class FixedPsuModel(PsuModel): 7 | MANUFACTURER = 'arista' 8 | DESCRIPTION = PsuDesc() 9 | 10 | class Fixed150AC(FixedPsuModel): 11 | CAPACITY = 150 12 | IDENTIFIERS = [ 13 | # Note: Used for Newport 14 | PsuIdent('PWR-440-AC', 'PWR-440-AC', Airflow.EXHAUST), 15 | ] 16 | 17 | class Fixed100AC(FixedPsuModel): 18 | CAPACITY = 100 19 | IDENTIFIERS = [ 20 | PsuIdent('PWR-545-AC', 'PWR-545-AC', Airflow.EXHAUST) 21 | ] 22 | -------------------------------------------------------------------------------- /arista/components/psu/helper.py: -------------------------------------------------------------------------------- 1 | 2 | from ...descs.fan import FanDesc, FanPosition 3 | from ...descs.psu import PsuDesc 4 | from ...descs.rail import RailDesc, RailDirection 5 | from ...descs.sensor import Position, SensorDesc 6 | 7 | def psuDescHelper(hasFans=True, maxRpm=None, minRpm=0, 8 | inputRailId=1, inputMaxVoltage=None, inputMinVoltage=None, 9 | outputRailId=1, outputMaxVoltage=None, outputMinVoltage=None, 10 | sensors=None): 11 | fans = [ 12 | FanDesc( 13 | fanId=1, 14 | name='psu%(psuId)d/%(fanId)d', 15 | position=FanPosition.OUTLET, 16 | maxRpm=maxRpm, 17 | minRpm=minRpm 18 | ) 19 | ] if hasFans else [] 20 | 21 | rails = [] 22 | if inputRailId is not None: 23 | rails.append(RailDesc( 24 | railId=inputRailId, 25 | direction=RailDirection.INPUT, 26 | maxVoltage=inputMaxVoltage, 27 | minVoltage=inputMinVoltage, 28 | )) 29 | if outputRailId is not None: 30 | rails.append(RailDesc( 31 | railId=outputRailId, 32 | direction=RailDirection.OUTPUT, 33 | maxVoltage=outputMaxVoltage, 34 | minVoltage=outputMinVoltage, 35 | )) 36 | 37 | sensors = sensors or [] 38 | sensors=[ 39 | SensorDesc( 40 | diode=i, 41 | name='Power supply %%(psuId)d %s sensor' % name, 42 | position=position, 43 | target=target, 44 | overheat=overheat, 45 | critical=critical, 46 | ) 47 | for i, (name, position, target, overheat, critical) in enumerate(sensors) 48 | ] 49 | 50 | return PsuDesc(fans=fans, rails=rails, sensors=sensors) 51 | -------------------------------------------------------------------------------- /arista/components/rpc.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.cause import ReloadCauseProviderHelper 3 | from ..core.component.component import Component 4 | from ..drivers.rpc import LinecardRpcClientDriver 5 | 6 | class RpcReloadCauseProviderImpl(ReloadCauseProviderHelper): 7 | def __init__(self, rpc): 8 | super().__init__(name=str(rpc)) 9 | self.rpc = rpc 10 | self.providers = [] 11 | 12 | def process(self): 13 | data = self.rpc.getReloadCauseData() 14 | if 'reports' not in data or not data['reports']: 15 | return 16 | self.providers = data['reports'][0]['providers'] 17 | 18 | def getRemoteProviders(self): 19 | return [ReloadCauseProviderHelper.fromDict(x) for x in self.providers] 20 | 21 | class LinecardRpcClient(Component): 22 | DRIVER = LinecardRpcClientDriver 23 | 24 | def __init__(self, *args, **kwargs): 25 | super().__init__(*args, **kwargs) 26 | self.inventory.addReloadCauseProvider(RpcReloadCauseProviderImpl(self)) 27 | 28 | def getReloadCauseData(self): 29 | return self.driver.getReloadCauseData() 30 | 31 | def addSeuReporter(self, component): 32 | reporter = self.driver.getSeuReporter(component) 33 | return self.inventory.addSeuReporter(reporter) 34 | -------------------------------------------------------------------------------- /arista/components/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/components/tests/__init__.py -------------------------------------------------------------------------------- /arista/components/tmp464.py: -------------------------------------------------------------------------------- 1 | 2 | from ..drivers.tmp468 import Tmp464KernelDriver 3 | 4 | from .tmp468 import Tmp468 5 | 6 | class Tmp464(Tmp468): 7 | DRIVER = Tmp464KernelDriver 8 | -------------------------------------------------------------------------------- /arista/components/tmp468.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.tmp468 import Tmp468KernelDriver 6 | 7 | class Tmp468(I2cComponent): 8 | DRIVER = Tmp468KernelDriver 9 | PRIORITY = Priority.THERMAL 10 | -------------------------------------------------------------------------------- /arista/components/vrm/mp8796b.py: -------------------------------------------------------------------------------- 1 | from ...core.component.i2c import I2cComponent 2 | from ...core.driver.user.i2c import I2cDevDriver 3 | 4 | class Mp8796B(I2cComponent): 5 | DRIVER = I2cDevDriver 6 | 7 | def setup(self): 8 | self.applyQuirks() 9 | -------------------------------------------------------------------------------- /arista/components/vrm/raa228228.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.component.i2c import I2cComponent 3 | from ...core.driver.user.i2c import I2cDevDriver 4 | from ...core.log import getLogger 5 | from ...core.quirk import Quirk 6 | 7 | logging = getLogger(__name__) 8 | 9 | class Raa228228GainQuirk(Quirk): 10 | def __init__(self, description=None, model=None, gain=None): 11 | self.description = description 12 | self.model = model 13 | self.gain = gain 14 | 15 | def __str__(self): 16 | return self.description or f'{self.__class__.__name__}' 17 | 18 | def run(self, component): 19 | model = component.driver.read_block_data(0x9a) 20 | if model != self.model: 21 | return 22 | component.driver.write_byte_data(0x00, 0x00) 23 | component.driver.write_bytes([0xde] + self.gain) 24 | if component.driver.read_bytes([0xde], 4) != self.gain: 25 | logging.error("Failed to apply %s", self.description) 26 | 27 | class Raa228228(I2cComponent): 28 | DRIVER = I2cDevDriver 29 | 30 | def setup(self): 31 | self.applyQuirks() 32 | -------------------------------------------------------------------------------- /arista/components/vrm/sic450.py: -------------------------------------------------------------------------------- 1 | 2 | from ...drivers.vrm.sic450 import Sic450UserDriver 3 | 4 | from . import Vrm 5 | 6 | class Sic450(Vrm): 7 | DRIVER = Sic450UserDriver 8 | -------------------------------------------------------------------------------- /arista/components/vrm/tps549d22.py: -------------------------------------------------------------------------------- 1 | 2 | from ...drivers.vrm.tps549d22 import Tps549D22UserDriver 3 | 4 | from . import Vrm 5 | 6 | class Tps549D22(Vrm): 7 | DRIVER = Tps549D22UserDriver 8 | -------------------------------------------------------------------------------- /arista/components/watchdog.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.config import Config 3 | from ..inventory.watchdog import Watchdog 4 | from ..drivers.scd.watchdog import WatchdogState 5 | 6 | class FakeWatchdog(Watchdog): 7 | 8 | MAX_TIMEOUT = 65535 9 | 10 | def __init__(self): 11 | self.state = WatchdogState(localStorage=Config().watchdog_state_file) 12 | 13 | def arm(self, timeout): 14 | self.state.arm(timeout) 15 | return True 16 | 17 | def stop(self): 18 | self.state.arm(0) 19 | return True 20 | 21 | def status(self): 22 | remaining = self.state.remaining() 23 | return { 24 | 'enabled': self.state.lastArmed != 0, 25 | 'timeout': self.state.lastTimeout, 26 | 'remainingTime': remaining, 27 | } 28 | -------------------------------------------------------------------------------- /arista/components/xcvr.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component import Priority 3 | from ..core.component.i2c import I2cComponent 4 | 5 | from ..drivers.xcvr import ( 6 | CmisEepromKernelDriver, 7 | SfpKernelDriver, 8 | QsfpKernelDriver, 9 | OsfpKernelDriver, 10 | ) 11 | 12 | class Xcvr(I2cComponent): 13 | PRIORITY = Priority.DEFAULT 14 | 15 | class CmisEeprom(Xcvr): 16 | DRIVER = CmisEepromKernelDriver 17 | 18 | class Ethernet(Xcvr): 19 | pass 20 | 21 | class Sfp(Xcvr): 22 | DRIVER = SfpKernelDriver 23 | 24 | class Qsfp(Xcvr): 25 | DRIVER = QsfpKernelDriver 26 | 27 | class Osfp(Xcvr): 28 | DRIVER = OsfpKernelDriver 29 | -------------------------------------------------------------------------------- /arista/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/core/__init__.py -------------------------------------------------------------------------------- /arista/core/backtrace.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | import sys 5 | import traceback 6 | 7 | def excepthookExtended(typ, value, tb): 8 | """ 9 | Print the usual traceback information, followed by a listing of all the 10 | local variables in each frame. 11 | """ 12 | traceback.print_exception(typ, value, tb) 13 | while True: 14 | if not tb.tb_next: 15 | break 16 | tb = tb.tb_next 17 | stack = [] 18 | f = tb.tb_frame 19 | while f: 20 | stack.append(f) 21 | f = f.f_back 22 | stack.reverse() 23 | print("Locals by frame, innermost last") 24 | for frame in stack: 25 | print() 26 | print("Frame %s in %s at line %s" % (frame.f_code.co_name, 27 | frame.f_code.co_filename, 28 | frame.f_lineno)) 29 | for key, val in frame.f_locals.items(): 30 | print("\t%20s = " % key, end='') 31 | # We have to be careful not to cause a new error in our error 32 | # printer! Calling str() on an unknown object could cause an 33 | # error we don't want. 34 | try: 35 | print(val) 36 | except Exception: # pylint: disable=broad-except 37 | print("") 38 | 39 | def loadBacktraceHook(): 40 | sys.excepthook = excepthookExtended 41 | -------------------------------------------------------------------------------- /arista/core/bootloader.py: -------------------------------------------------------------------------------- 1 | 2 | from .component.component import Component 3 | 4 | from ..libs.procfs import getCmdlineDict 5 | from ..inventory.programmable import Programmable 6 | 7 | class AbootProgrammable(Programmable): 8 | def __init__(self, aboot): 9 | self.aboot = aboot 10 | 11 | def getComponent(self): 12 | return self.aboot 13 | 14 | def getDescription(self): 15 | return 'Bootloader' 16 | 17 | def getVersion(self): 18 | return self.aboot.getVersion() 19 | 20 | class Aboot(Component): 21 | def __init__(self, *args, **kwargs): 22 | super(Aboot, self).__init__(*args, **kwargs) 23 | self.inventory.addProgrammable(AbootProgrammable(self)) 24 | 25 | def getVersion(self): 26 | return getCmdlineDict().get('Aboot', 'N/A') 27 | -------------------------------------------------------------------------------- /arista/core/component/i2c.py: -------------------------------------------------------------------------------- 1 | 2 | from .component import Component 3 | from ..quirk import Quirk 4 | 5 | class I2cRegisterQuirk(Quirk): # pylint: disable=abstract-method 6 | def __init__(self, addr, data, description=None): 7 | self.addr = addr 8 | self.data = data 9 | self.description = description 10 | 11 | def __str__(self): 12 | return self.description or f'{self.__class__.__name__}({self.addr})' 13 | 14 | class I2cByteQuirk(I2cRegisterQuirk): 15 | def run(self, component): 16 | component.driver.write_byte_data(self.addr, self.data) 17 | 18 | class I2cBlockQuirk(I2cRegisterQuirk): 19 | def run(self, component): 20 | component.driver.write_bytes([self.addr, len(self.data)] + self.data) 21 | 22 | class I2cComponent(Component): 23 | pass 24 | -------------------------------------------------------------------------------- /arista/core/component/pci.py: -------------------------------------------------------------------------------- 1 | 2 | from .component import Component 3 | 4 | class PciComponent(Component): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/core/component/slot.py: -------------------------------------------------------------------------------- 1 | 2 | from .component import Component 3 | 4 | class SlotComponent(Component): 5 | def getPresence(self): 6 | raise NotImplementedError 7 | -------------------------------------------------------------------------------- /arista/core/component/unmanaged.py: -------------------------------------------------------------------------------- 1 | 2 | from .component import Component 3 | 4 | class UnmanagedComponent(Component): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/core/cpu.py: -------------------------------------------------------------------------------- 1 | 2 | from .bootloader import Aboot 3 | from .sku import Sku 4 | 5 | from ..components.cookie import PlatformCookieComponent 6 | 7 | class Cpu(Sku): 8 | def __init__(self, *args, **kwargs): 9 | super(Cpu, self).__init__(*args, **kwargs) 10 | self.bootloader = self.newComponent(Aboot) 11 | self.cookies = self.newComponent(PlatformCookieComponent) 12 | -------------------------------------------------------------------------------- /arista/core/desc.py: -------------------------------------------------------------------------------- 1 | 2 | class HwDesc(object): 3 | 4 | OID_FIELD = None 5 | 6 | def __init__(self, **kwargs): 7 | self.setAttrs(**kwargs) 8 | 9 | @classmethod 10 | def __lid2oid__(cls, lid): 11 | return lid 12 | 13 | @classmethod 14 | def __oid2lid__(cls, oid): 15 | return oid 16 | 17 | def __getoid__(self): 18 | if self.OID_FIELD is None: 19 | raise NotImplementedError 20 | return self.__lid2oid__(getattr(self, self.OID_FIELD)) 21 | 22 | def __setoid__(self, oid): 23 | setattr(self, self.OID_FIELD, self.__oid2lid__(oid)) 24 | 25 | def setAttrs(self, **kwargs): 26 | for key, value in kwargs.items(): 27 | setattr(self, key, value) 28 | 29 | def __diag__(self, ctx): 30 | return { k : v.__diag__(ctx) if isinstance(v, HwDesc) else v 31 | for k, v in self.__dict__.items() } 32 | -------------------------------------------------------------------------------- /arista/core/diag.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function 2 | 3 | class DiagContext(object): 4 | def __init__(self, performIo=True, recursive=False, safe=False): 5 | self.performIo = performIo 6 | self.recursive = recursive 7 | self.safe = safe 8 | self.inventories = set() # set of visited inventories 9 | -------------------------------------------------------------------------------- /arista/core/domain.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.component.unmanaged import UnmanagedComponent 3 | 4 | class PowerDomain(UnmanagedComponent): 5 | def __init__(self, enabled=None, **kwargs): 6 | super(PowerDomain, self).__init__(**kwargs) 7 | self.enabledFn = enabled 8 | if self.enabledFn is None: 9 | self.enabledFn = lambda: True 10 | 11 | def isEnabled(self): 12 | return self.enabledFn() 13 | -------------------------------------------------------------------------------- /arista/core/driver/kernel/pci.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | 4 | from ...utils import FileWaiter, MmapResource 5 | 6 | from . import KernelDriver 7 | 8 | class PciKernelDriver(KernelDriver): 9 | def __init__(self, addr=None, registerCls=None, **kwargs): 10 | super(PciKernelDriver, self).__init__(**kwargs) 11 | self.addr = addr 12 | self.regs = registerCls(self) if registerCls is not None else None 13 | self.mmap_ = None 14 | 15 | @property 16 | def mmap(self): 17 | if self.mmap_ is None: 18 | path = os.path.join(self.addr.getSysfsPath(), "resource0") 19 | if not FileWaiter(path, 5).waitFileReady(): 20 | raise IOError('Mmap failed because file %s doesn\'t exist' % path) 21 | self.mmap_ = MmapResource(path) 22 | if not self.mmap_.map(): 23 | raise IOError('Failed to mmap file %s' % path) 24 | return self.mmap_ 25 | 26 | def write(self, addr, value): 27 | self.mmap.write32(addr, value) 28 | 29 | def read(self, addr): 30 | return self.mmap.read32(addr) 31 | 32 | def getSysfsPath(self): 33 | return self.addr.getSysfsPath() 34 | -------------------------------------------------------------------------------- /arista/core/driver/user/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .. import Driver 3 | 4 | class UserDriver(Driver): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/core/exception.py: -------------------------------------------------------------------------------- 1 | 2 | class UnknownPlatformError(Exception): 3 | pass 4 | 5 | -------------------------------------------------------------------------------- /arista/core/fabric.py: -------------------------------------------------------------------------------- 1 | 2 | from .card import Card 3 | 4 | class Fabric(Card): # pylint: disable=abstract-method 5 | ABSOLUTE_CARD_OFFSET = 51 6 | -------------------------------------------------------------------------------- /arista/core/fixed.py: -------------------------------------------------------------------------------- 1 | from .component import Priority 2 | from .inventory import Inventory 3 | from .metainventory import MetaInventory 4 | from .platform import getSysEepromData 5 | from .sku import Sku 6 | 7 | class FixedSystem(Sku): 8 | 9 | CHASSIS = None 10 | 11 | def __init__(self, inventory=None, **kwargs): 12 | inventory = inventory or Inventory() 13 | super(FixedSystem, self).__init__(inventory=inventory, **kwargs) 14 | 15 | def getEeprom(self): 16 | return getSysEepromData() 17 | 18 | def getInventory(self): 19 | return MetaInventory(self.iterInventory()) 20 | 21 | def setup(self, filters=Priority.defaultFilter): 22 | super(FixedSystem, self).setup() 23 | super(FixedSystem, self).finish(filters) 24 | 25 | def __str__(self): 26 | return '%s()' % self.__class__.__name__ 27 | 28 | def getCookies(self): 29 | return self.cpu.cookies 30 | 31 | class FixedChassis(object): 32 | FAN_SLOTS = None 33 | FAN_COUNT = None 34 | PSU_SLOTS = None 35 | HEIGHT_RU = None 36 | -------------------------------------------------------------------------------- /arista/core/linecard.py: -------------------------------------------------------------------------------- 1 | 2 | from .card import Card 3 | from .provision import ProvisionMode 4 | 5 | class LCpuCtx(object): 6 | def __init__(self, provision=ProvisionMode.NONE): 7 | self.provision = provision 8 | 9 | class Linecard(Card): # pylint: disable=abstract-method 10 | ABSOLUTE_CARD_OFFSET = 3 11 | -------------------------------------------------------------------------------- /arista/core/port.py: -------------------------------------------------------------------------------- 1 | from ..descs.xcvr import Osfp, Qsfp, QsfpDD, Rj45, Sfp 2 | 3 | class PortLayout(): 4 | def __init__(self, *args): 5 | self.ports = [p for pgen in args for p in pgen] 6 | 7 | def getEthernets(self): 8 | return [p for p in self.ports if isinstance(p, Rj45)] 9 | 10 | def getSfps(self): 11 | return [p for p in self.ports if isinstance(p, Sfp)] 12 | 13 | def getQsfps(self): 14 | return [p for p in self.ports if 15 | isinstance(p, Qsfp) and not isinstance(p, QsfpDD)] 16 | 17 | def getOsfps(self): 18 | return [p for p in self.ports if isinstance(p, (Osfp, QsfpDD))] 19 | 20 | def getAllPorts(self): 21 | return self.ports 22 | 23 | def getPorts(self, *args): 24 | return [p for p in self.ports if isinstance(p, args)] 25 | 26 | def getPort(self, index): 27 | filtered = [p for p in self.ports if p.index == index] 28 | if not filtered: 29 | return None 30 | return filtered[0] 31 | -------------------------------------------------------------------------------- /arista/core/provision.py: -------------------------------------------------------------------------------- 1 | 2 | import enum 3 | import os 4 | 5 | from .config import flashPath 6 | 7 | class ProvisionMode(enum.IntEnum): 8 | NONE = 0 9 | STATIC = 1 10 | 11 | def __str__(self): 12 | return self.name.lower() 13 | 14 | class ProvisionConfig(object): 15 | 16 | CONFIG_PATH = flashPath('provision/%d/.provision') 17 | 18 | def __init__(self, slotId): 19 | self.configPath_ = self.CONFIG_PATH % slotId 20 | 21 | def loadMode(self): 22 | if os.path.exists(self.configPath_): 23 | return ProvisionMode.STATIC 24 | return ProvisionMode.NONE 25 | 26 | def writeMode(self, mode): 27 | if mode == ProvisionMode.STATIC: 28 | try: 29 | with open(self.configPath_, 'w'): 30 | pass 31 | except IOError: 32 | pass 33 | return 34 | 35 | try: 36 | os.remove(self.configPath_) 37 | except OSError: 38 | pass 39 | -------------------------------------------------------------------------------- /arista/core/quirk.py: -------------------------------------------------------------------------------- 1 | 2 | import subprocess 3 | 4 | from .log import getLogger 5 | from .utils import inSimulation 6 | 7 | logging = getLogger(__name__) 8 | 9 | class Quirk(object): 10 | 11 | DELAYED = False 12 | 13 | def run(self, component): 14 | raise NotImplementedError 15 | 16 | class QuirkCmd(Quirk): 17 | def __init__(self, cmd, description): 18 | self.description = description 19 | self.cmd = cmd 20 | 21 | def __str__(self): 22 | return self.description 23 | 24 | def run(self, component): 25 | if not inSimulation(): 26 | subprocess.check_output(self.cmd) 27 | 28 | class PciConfigQuirk(QuirkCmd): # TODO: reparent when using PciTopology 29 | def __init__(self, addr, expr, description): 30 | super().__init__(['setpci', '-s', str(addr), expr], description) 31 | self.addr = addr 32 | self.expr = expr 33 | -------------------------------------------------------------------------------- /arista/core/sku.py: -------------------------------------------------------------------------------- 1 | 2 | from .component.component import Component 3 | from .hwapi import HwApi 4 | from .port import PortLayout 5 | 6 | class Sku(Component): 7 | 8 | PLATFORM = None 9 | SID = None 10 | SKU = None 11 | 12 | DEFAULT_HWAPI = (0, 0) 13 | 14 | PORTS = PortLayout() 15 | 16 | MAX_POWER_DRAW = 0 17 | TYP_POWER_DRAW = 0 18 | 19 | LED_FP_TRICOLOR = False 20 | 21 | def __init__(self, *args, **kwargs): 22 | self.hwApi = kwargs.pop('hwApi', None) 23 | super(Sku, self).__init__(*args, **kwargs) 24 | 25 | def getEeprom(self): 26 | return {} 27 | 28 | def getPresence(self): 29 | return True 30 | 31 | def poweredOn(self): 32 | return True 33 | 34 | def getHwApi(self): 35 | if not self.hwApi: 36 | self.hwApi = HwApi(*self.getEeprom().get('HwApi', self.DEFAULT_HWAPI)) 37 | return self.hwApi 38 | 39 | def genDiag(self, ctx): 40 | output = super(Sku, self).genDiag(ctx) 41 | output['eeprom'] = self.getEeprom() if ctx.performIo else None 42 | return output 43 | -------------------------------------------------------------------------------- /arista/core/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/core/tests/__init__.py -------------------------------------------------------------------------------- /arista/core/tests/hwapi.py: -------------------------------------------------------------------------------- 1 | 2 | from ..hwapi import HwApi 3 | from ...tests.testing import unittest 4 | 5 | class HwApiTest(unittest.TestCase): 6 | def testEqual(self): 7 | self.assertEqual(HwApi(2), HwApi(2)) 8 | self.assertEqual(HwApi(2), HwApi(2, 0)) 9 | self.assertEqual(HwApi(2, 0), HwApi(2)) 10 | 11 | def testGreater(self): 12 | self.assertGreater(HwApi(3), HwApi(2)) 13 | self.assertGreater(HwApi(3), HwApi(2, 1)) 14 | self.assertGreater(HwApi(3, 1), HwApi(3, 0)) 15 | self.assertGreater(HwApi(3, 1), HwApi(3)) 16 | 17 | def testLess(self): 18 | self.assertLess(HwApi(2), HwApi(3)) 19 | self.assertLess(HwApi(2, 1), HwApi(3)) 20 | self.assertLess(HwApi(2, 0), HwApi(2, 1)) 21 | self.assertLess(HwApi(2), HwApi(2, 1)) 22 | 23 | def testGreaterEqual(self): 24 | self.assertGreaterEqual(HwApi(2), HwApi(2)) 25 | self.assertGreaterEqual(HwApi(2), HwApi(2, 0)) 26 | self.assertGreaterEqual(HwApi(3), HwApi(2)) 27 | self.assertGreaterEqual(HwApi(3), HwApi(2, 1)) 28 | self.assertGreaterEqual(HwApi(2, 1), HwApi(2, 1)) 29 | 30 | def testLessEqual(self): 31 | self.assertLessEqual(HwApi(2), HwApi(2)) 32 | self.assertLessEqual(HwApi(2, 0), HwApi(2)) 33 | self.assertLessEqual(HwApi(2), HwApi(3)) 34 | self.assertLessEqual(HwApi(2, 1), HwApi(3)) 35 | self.assertLessEqual(HwApi(2, 1), HwApi(2, 1)) 36 | 37 | if __name__ == '__main__': 38 | unittest.main() 39 | -------------------------------------------------------------------------------- /arista/core/tests/mockchassis.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.cpu import Cpu 3 | from ...core.pci import PciRoot 4 | from ...core.supervisor import Supervisor 5 | 6 | from ...components.cookie import CookieComponentBase, SlotCookieComponent 7 | from ...components.scd import Scd 8 | 9 | class MockCookieComponent(CookieComponentBase): 10 | def __init__(self, *args, **kwargs): 11 | super().__init__(*args, slotId=0, **kwargs) 12 | 13 | def addLinecard(self, card): 14 | card.cookies = card.newComponent(SlotCookieComponent, 15 | slotId=card.slot.slotId, 16 | platformCookies=self) 17 | 18 | def loadCookieFile(self): 19 | pass 20 | 21 | def storeCauses(self): 22 | pass 23 | 24 | class MockCpu(Cpu): 25 | def __init__(self): 26 | super(Cpu, self).__init__() 27 | self.pciRoot = PciRoot() 28 | scdPort = self.pciRoot.rootPort(bus=0x0f) 29 | self.scd = self.pciRoot.newComponent(Scd, addr=scdPort.addr) 30 | self.cookies = self.newComponent(MockCookieComponent) 31 | 32 | class MockSupervisor(Supervisor): 33 | def addCpuComplex(self): 34 | self.cpu = MockCpu() 35 | 36 | def getPciPort(self, bus): 37 | return self.cpu.pciRoot.rootPort(bus=bus) 38 | 39 | def getSmbus(self, bus): 40 | return self.cpu.scd.getSmbus(bus) 41 | 42 | def getCookies(self): 43 | return self.cpu.cookies 44 | -------------------------------------------------------------------------------- /arista/core/thermal_control.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function 2 | 3 | MIN_FAN_SPEED = 30 4 | MAX_FAN_SPEED = 100 5 | 6 | def sensorsToFanSpeed(sensors): 7 | targetFanSpeed = MIN_FAN_SPEED 8 | for sensor in sensors: 9 | if not sensor.get_presence(): 10 | continue 11 | desc = sensor.get_inventory_object().getDesc() 12 | maxTemp = min(desc.overheat, desc.critical) 13 | if not int(desc.target) or not int(maxTemp): 14 | continue 15 | halfwayTemp = (desc.target + maxTemp) / 2 16 | temp = sensor.get_temperature() 17 | if temp < halfwayTemp: 18 | continue 19 | elif temp >= maxTemp: 20 | targetFanSpeed = MAX_FAN_SPEED 21 | continue 22 | newFanSpeed = (temp - halfwayTemp) / (maxTemp - halfwayTemp) * \ 23 | (MAX_FAN_SPEED - MIN_FAN_SPEED) + \ 24 | MIN_FAN_SPEED 25 | targetFanSpeed = max(targetFanSpeed, newFanSpeed) 26 | return targetFanSpeed 27 | -------------------------------------------------------------------------------- /arista/core/version.py: -------------------------------------------------------------------------------- 1 | 2 | from collections import OrderedDict 3 | 4 | try: 5 | # pylint: disable=unused-import 6 | from ..__version__ import __VERSION__, __DATE__ 7 | except ImportError: 8 | __VERSION__ = "unknown" 9 | __DATE__ = "unknown" 10 | 11 | def getVersionInfo(): 12 | return OrderedDict([ 13 | ('version', __VERSION__), 14 | ('date', __DATE__), 15 | ]) 16 | 17 | -------------------------------------------------------------------------------- /arista/daemon/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.dynload import importSubmodules 3 | 4 | __all__ = importSubmodules(__package__).keys() 5 | -------------------------------------------------------------------------------- /arista/daemon/cookies.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.daemon import registerDaemonFeature, PollDaemonFeature 3 | from ..core.log import getLogger 4 | from ..core.supervisor import Supervisor 5 | 6 | logging = getLogger(__name__) 7 | 8 | @registerDaemonFeature() 9 | class CookiesFeature(PollDaemonFeature): 10 | 11 | NAME = 'cookies' 12 | INTERVAL = 3 13 | 14 | @classmethod 15 | def runnable(cls, daemon): 16 | return isinstance(daemon.platform, Supervisor) 17 | 18 | def checkProviders(self, unit): 19 | causes = {} 20 | for p in unit.getInventory().getReloadCauseProviders(): 21 | slotCauses = p.poll() 22 | assert p.getSourceName() not in causes 23 | causes[p.getSourceName()] = slotCauses 24 | return causes 25 | 26 | def init(self): 27 | platform = self.daemon.platform 28 | cookies = platform.getCookies() 29 | cookies.loadCookieFile() 30 | super().init() 31 | 32 | def callback(self, elapsed): 33 | platform = self.daemon.platform 34 | cookies = platform.getCookies() 35 | 36 | cookies.poll() 37 | cookies.storeCauses() 38 | -------------------------------------------------------------------------------- /arista/daemon/dpm.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.daemon import registerDaemonFeature, PollDaemonFeature 3 | from ..core.log import getLogger 4 | 5 | logging = getLogger(__name__) 6 | 7 | @registerDaemonFeature() 8 | class DpmMonitorFeature(PollDaemonFeature): 9 | 10 | NAME = 'dpm' 11 | INTERVAL = 10 * 60 12 | 13 | def init(self): 14 | PollDaemonFeature.init(self) 15 | self.providers = [] 16 | for rcp in self.daemon.platform.getInventory().getReloadCauseProviders(): 17 | logging.info('%s: %s marked for periodic clock sync', self, rcp) 18 | self.providers.append(rcp) 19 | 20 | def callback(self, elapsed): 21 | for rcp in self.providers: 22 | logging.debug('%s: updating %s rtc', self, rcp) 23 | rcp.setRealTimeClock() 24 | -------------------------------------------------------------------------------- /arista/daemon/jsonrpc.py: -------------------------------------------------------------------------------- 1 | from ..core.daemon import registerDaemonFeature, OneShotFeature 2 | from ..core.config import Config 3 | from ..core.log import getLogger 4 | from ..core.supervisor import Supervisor 5 | from ..core.linecard import Linecard 6 | from ..utils.rpc.api import RpcSupervisorApi, RpcLinecardApi 7 | from ..utils.rpc.server import RpcServer 8 | 9 | logging = getLogger(__name__) 10 | 11 | @registerDaemonFeature() 12 | class JsonRpcDaemonFeature(OneShotFeature): 13 | NAME = 'jsonrpc' 14 | 15 | def __init__(self): 16 | OneShotFeature.__init__(self) 17 | self.server = None 18 | 19 | def run(self): 20 | hosts = [] 21 | api = None 22 | 23 | if isinstance(self.daemon.platform, Supervisor): 24 | logging.info('%s: setting up server on supervisor', self) 25 | hosts = [Config().api_rpc_host, Config().api_rpc_sup] 26 | api = RpcSupervisorApi(self.daemon.platform) 27 | elif isinstance(self.daemon.platform, Linecard): 28 | logging.info('%s: setting up server on linecard', self) 29 | hosts = [Config().api_rpc_lcx.format(self.daemon.platform.getSlotId())] 30 | api = RpcLinecardApi(self.daemon.platform) 31 | else: 32 | logging.info('%s: not supervisor or linecard, nothing to do', self) 33 | return 34 | 35 | port = Config().api_rpc_port 36 | self.server = RpcServer(hosts, port, api) 37 | self.daemon.loop.create_task(self.server.start()) 38 | -------------------------------------------------------------------------------- /arista/daemon/mac.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from ..core.daemon import registerDaemonFeature, OneShotFeature 5 | from ..core.log import getLogger 6 | from ..core.platform import getSysEepromData 7 | from ..core.utils import getCmdlineDict 8 | 9 | logging = getLogger(__name__) 10 | 11 | @registerDaemonFeature() 12 | class MacOneShotFeature(OneShotFeature): 13 | 14 | NAME = 'mac' 15 | 16 | def readMacAddress(self, intfName): 17 | path = '/sys/class/net/%s/address' % intfName 18 | with open(path) as f: 19 | return f.read().rstrip() 20 | 21 | def run(self): 22 | intfName = 'eth0' 23 | currentMac = self.readMacAddress(intfName) 24 | desiredMac = getSysEepromData().get('MAC', '00:00:00:00:00:00') 25 | currentMacValue = int(currentMac.replace(':', ''), 16) 26 | desiredMacValue = int(desiredMac.replace(':', ''), 16) 27 | if currentMac == desiredMac: 28 | logging.info('mac address of %s is properly set to %s', intfName, 29 | currentMac) 30 | elif currentMacValue == desiredMacValue + 1: 31 | logging.warning('mac address of %s is not set properly. is %s should be %s' 32 | ' (likely coming from EOS via fast-reboot)', 33 | intfName, currentMac, desiredMac) 34 | else: 35 | logging.error('mac address of %s is not set properly. is %s should be %s', 36 | intfName, currentMac, desiredMac) 37 | for key, value in getCmdlineDict().items(): 38 | if key.startswith('hwaddr_'): 39 | logging.info('cmdline: %s=%s', key, value) 40 | -------------------------------------------------------------------------------- /arista/daemon/quirk.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.daemon import registerDaemonFeature, OneShotFeature 3 | from ..core.log import getLogger 4 | 5 | logging = getLogger(__name__) 6 | 7 | @registerDaemonFeature() 8 | class QuirkOneShotFeature(OneShotFeature): 9 | 10 | NAME = 'quirk' 11 | 12 | def run(self): 13 | for component in self.daemon.platform.iterComponents(filters=None): 14 | if getattr(component, 'quirks', []): 15 | logging.info('%s: applying quirks on %s', self, component) 16 | component.applyQuirks(delayed=True) 17 | -------------------------------------------------------------------------------- /arista/daemon/seu.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from ..core.daemon import registerDaemonFeature, PollDaemonFeature 5 | from ..core.log import getLogger 6 | 7 | logging = getLogger(__name__) 8 | 9 | @registerDaemonFeature() 10 | class SeuDaemonFeature(PollDaemonFeature): 11 | 12 | NAME = 'seu' 13 | INTERVAL = 60 14 | 15 | def init(self): 16 | PollDaemonFeature.init(self) 17 | self.seuDetected = {} # pylint: disable=attribute-defined-outside-init 18 | for reporter in self.daemon.platform.getInventory().getSeuReporters(): 19 | component = reporter.getComponent() 20 | self.seuDetected[component] = False 21 | if reporter.powerCycleOnSeu(): 22 | logging.info('%s: disabling powercycle on SEU', component) 23 | reporter.powerCycleOnSeu(False) 24 | else: 25 | logging.info('%s: powercycle on SEU already disabled', component) 26 | 27 | def callback(self, elapsed): 28 | for reporter in self.daemon.platform.getInventory().getSeuReporters(): 29 | component = reporter.getComponent() 30 | detected = self.seuDetected.get(component) 31 | if not detected and reporter.hasSeuError(): 32 | logging.error('A SEU error was detected on %s', component) 33 | logging.info('The impact can vary from nothing and in rare cases ' 34 | 'unexpected behavior') 35 | logging.info('Power cycling the system would restore it to a ' 36 | 'clean slate') 37 | self.seuDetected[component] = True 38 | -------------------------------------------------------------------------------- /arista/descs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/descs/__init__.py -------------------------------------------------------------------------------- /arista/descs/fan.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | from ..core.desc import HwDesc 4 | from ..core.cooling import Airflow 5 | 6 | class FanPosition(str, Enum): 7 | UNKNOWN = 'unknown' 8 | INLET = 'inlet' 9 | OUTLET = 'outlet' 10 | 11 | class FanDesc(HwDesc): 12 | 13 | OID_FIELD = 'fanId' 14 | 15 | def __init__(self, fanId, name='fan%(namespaceId)s%(fanId)s', 16 | position=FanPosition.UNKNOWN, airflow=Airflow.UNKNOWN, 17 | model='N/A', minRpm=None, maxRpm=None, namespaceFn=None, 18 | **kwargs): 19 | super(FanDesc, self).__init__(**kwargs) 20 | self.fmt = name 21 | self.name = None 22 | self.fanId = fanId 23 | self.position = position 24 | self.airflow = airflow 25 | self.model = model 26 | self.minRpm = minRpm 27 | self.maxRpm = maxRpm 28 | self.namespaceFn = namespaceFn 29 | 30 | def renderName(self, **kwargs): 31 | values = kwargs.copy() 32 | values.update(self.__dict__) 33 | values['namespaceId'] = f'{self.namespaceFn()}/' if self.namespaceFn else '' 34 | self.name = self.fmt % values 35 | 36 | class FanSlotDesc(HwDesc): 37 | 38 | OID_FIELD = 'slotId' 39 | 40 | def __init__(self, slotId, name=None, fans=None, **kwargs): 41 | super(FanSlotDesc, self).__init__(**kwargs) 42 | self.slotId = slotId 43 | self.name = name 44 | self.fans = fans 45 | -------------------------------------------------------------------------------- /arista/descs/gpio.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.desc import HwDesc 3 | 4 | class GpioDesc(HwDesc): 5 | def __init__(self, name, addr=None, bit=None, ro=False, activeLow=False, 6 | **kwargs): 7 | super(GpioDesc, self).__init__(**kwargs) 8 | 9 | self.name = name 10 | self.addr = addr 11 | self.bit = bit 12 | self.ro = ro 13 | self.activeLow = activeLow 14 | -------------------------------------------------------------------------------- /arista/descs/led.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.desc import HwDesc 3 | 4 | class LedColor(object): 5 | GREEN = 'green' 6 | RED = 'red' 7 | AMBER = 'amber' 8 | BLUE = 'blue' 9 | OFF = 'off' 10 | 11 | class LedDesc(HwDesc): 12 | def __init__(self, name=None, colors=None, blinking=False, **kwargs): 13 | super(LedDesc, self).__init__(**kwargs) 14 | self.name = name 15 | self.colors = colors 16 | self.blinking = blinking 17 | -------------------------------------------------------------------------------- /arista/descs/psu.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.desc import HwDesc 3 | 4 | class PsuDesc(HwDesc): 5 | 6 | OID_FIELD = 'psuId' 7 | 8 | def __init__(self, psuId=None, led=None, sensors=None, fans=None, rails=None, 9 | **kwargs): 10 | super(PsuDesc, self).__init__(**kwargs) 11 | self.psuId = psuId 12 | self.led = led 13 | self.sensors = sensors or [] 14 | self.fans = fans or [] 15 | self.rails = rails or [] 16 | 17 | def setPsuId(self, psuId): 18 | self.psuId = psuId 19 | for sensor in self.sensors: 20 | sensor.renderName(psuId=psuId) 21 | for fan in self.fans: 22 | fan.renderName(psuId=psuId) 23 | for rail in self.rails: 24 | rail.renderName(psuId=psuId) 25 | 26 | def setAirflow(self, airflow): 27 | for fan in self.fans: 28 | fan.airflow = airflow 29 | -------------------------------------------------------------------------------- /arista/descs/rail.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.desc import HwDesc 3 | 4 | class RailDirection(object): 5 | INPUT = 'input' 6 | OUTPUT = 'output' 7 | 8 | class RailDesc(HwDesc): 9 | 10 | OID_FIELD = 'railId' 11 | 12 | def __init__(self, railId, name='%(direction)s%(railId)s', direction=None, 13 | current=None, power=None, voltage=None, **kwargs): 14 | super(RailDesc, self).__init__(**kwargs) 15 | self.railId = railId 16 | self.fmt = name 17 | self.direction = direction 18 | self.name = None 19 | self.current = current 20 | self.power = power 21 | self.voltage = voltage 22 | 23 | def renderName(self, **kwargs): 24 | values = kwargs.copy() 25 | values.update(self.__dict__) 26 | self.name = self.fmt % values 27 | 28 | class VoltageDesc(HwDesc): 29 | 30 | OID_FIELD = 'voltId' 31 | 32 | def __init__(self, voltId, name=None, direction=None, **kwargs): 33 | super(VoltageDesc, self).__init__(**kwargs) 34 | self.voltId = voltId 35 | self.name = name 36 | self.direction = direction 37 | 38 | class CurrentDesc(HwDesc): 39 | 40 | OID_FIELD = 'currId' 41 | 42 | def __init__(self, currId, name=None, direction=None, **kwargs): 43 | super(CurrentDesc, self).__init__(**kwargs) 44 | self.currId = currId 45 | self.name = name 46 | self.direction = direction 47 | 48 | class PowerDesc(HwDesc): 49 | 50 | OID_FIELD = 'powerId' 51 | 52 | def __init__(self, powerId, name=None, direction=None, **kwargs): 53 | super(PowerDesc, self).__init__(**kwargs) 54 | self.powerId = powerId 55 | self.name = name 56 | self.direction = direction 57 | -------------------------------------------------------------------------------- /arista/descs/reset.py: -------------------------------------------------------------------------------- 1 | from ..core.desc import HwDesc 2 | 3 | class ResetDesc(HwDesc): 4 | def __init__(self, name, addr=None, bit=None, activeLow=False, auto=True, 5 | **kwargs): 6 | super(ResetDesc, self).__init__(**kwargs) 7 | self.name = name 8 | self.addr = addr 9 | self.bit = bit 10 | self.activeLow = activeLow 11 | self.auto = auto 12 | -------------------------------------------------------------------------------- /arista/descs/sensor.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.desc import HwDesc 3 | 4 | class Position(object): 5 | INLET = 'inlet' 6 | OUTLET = 'outlet' 7 | OTHER = 'other' 8 | 9 | class SensorDesc(HwDesc): 10 | 11 | OID_FIELD = 'diode' 12 | 13 | def __init__(self, diode, name=None, position=Position.OTHER, 14 | target=0., overheat=0., critical=0., 15 | low=0.0, lcritical=-5.0, **kwargs): 16 | super(SensorDesc, self).__init__(**kwargs) 17 | self.diode = diode 18 | self.fmt = name 19 | self.name = name 20 | self.position = position 21 | self.target = float(target) 22 | self.overheat = float(overheat) 23 | self.critical = float(critical) 24 | self.low = float(low) 25 | self.lcritical = float(lcritical) 26 | 27 | def renderName(self, **kwargs): 28 | values = kwargs.copy() 29 | values.update(self.__dict__) 30 | self.name = self.fmt % values 31 | 32 | @classmethod 33 | def __oid2lid__(cls, oid): 34 | return oid - 1 35 | 36 | @classmethod 37 | def __lid2oid__(cls, lid): 38 | return lid + 1 39 | -------------------------------------------------------------------------------- /arista/descs/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/descs/tests/__init__.py -------------------------------------------------------------------------------- /arista/descs/tests/types.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import absolute_import, division, print_function 3 | 4 | from ...tests.testing import unittest 5 | from ..fan import FanDesc 6 | from ..led import LedDesc 7 | from ..psu import PsuDesc 8 | from ..sensor import Position, SensorDesc 9 | 10 | class DescTest(unittest.TestCase): 11 | def _testAttributes(self, cls, **kwargs): 12 | desc = cls(**kwargs) 13 | for k, v in kwargs.items(): 14 | assert hasattr(desc, k) 15 | assert getattr(desc, k) == v 16 | 17 | def testFanDesc(self): 18 | self._testAttributes(FanDesc, fanId=1, extra='blah') 19 | 20 | def testLedDesc(self): 21 | self._testAttributes(LedDesc, name='led', colors=[ 'blue', 'red' ], 22 | extra='blah') 23 | 24 | def testPsuDesc(self): 25 | self._testAttributes(PsuDesc, psuId=1, extra='blah') 26 | 27 | def testSensorDesc(self): 28 | self._testAttributes(SensorDesc, diode=3, name='sensor', 29 | position=Position.OTHER, target=10, overheat=20, 30 | critical=30, extra='blah') 31 | 32 | if __name__ == "__main__": 33 | unittest.main() 34 | -------------------------------------------------------------------------------- /arista/descs/xcvr.py: -------------------------------------------------------------------------------- 1 | from ..core.desc import HwDesc 2 | 3 | class Xcvr(HwDesc): 4 | LANES = None 5 | SPEED = None 6 | 7 | def __init__(self, index, speed=None, lanes=None, leds=1, **kwargs): 8 | super(Xcvr, self).__init__(**kwargs) 9 | self.index = index 10 | self.leds = leds 11 | self.lanes = lanes or self.LANES 12 | self.speed = speed or self.SPEED 13 | 14 | def __str__(self): 15 | return f'{self.__class__.__name__}(index={self.index})' 16 | 17 | class Rj45(Xcvr): 18 | LANES = 1 19 | SPEED = 1000 20 | 21 | class Sfp(Xcvr): 22 | LANES = 1 23 | SPEED = 10000 24 | 25 | class Sfp28(Sfp): 26 | SPEED = 25000 27 | 28 | class Sfp56(Sfp28): 29 | SPEED = 50000 30 | 31 | class Qsfp(Xcvr): 32 | LANES = 4 33 | SPEED = 10000 34 | 35 | class QsfpPlus(Qsfp): 36 | pass 37 | 38 | class Qsfp28(QsfpPlus): 39 | SPEED = 25000 40 | 41 | class Qsfp56(Qsfp28): 42 | SPEED = 50000 43 | 44 | class QsfpDD(Qsfp56): 45 | LANES = 8 46 | 47 | class Osfp(Xcvr): 48 | LANES = 8 49 | SPEED = 50000 50 | 51 | class Osfp800(Osfp): 52 | SPEED = 100000 53 | -------------------------------------------------------------------------------- /arista/drivers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/drivers/__init__.py -------------------------------------------------------------------------------- /arista/drivers/cookie.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..core.config import flashPath 4 | from ..core.driver.user import UserDriver 5 | 6 | class SonicReloadCauseCookieDriver(UserDriver): 7 | def __init__(self, slotId=None, filePath=None, **kwargs): # pylint: disable=unused-argument 8 | super().__init__(**kwargs) 9 | self.filePath = filePath or flashPath('reboot-cause/reboot-cause.txt') 10 | 11 | def getSoftwareCause(self): 12 | if os.path.exists(self.filePath): 13 | with open(self.filePath, 'r', encoding='utf-8') as f: 14 | return f.readline() 15 | return None 16 | -------------------------------------------------------------------------------- /arista/drivers/coretemp.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel import KernelDriver 3 | 4 | class CoretempKernelDriver(KernelDriver): 5 | MODULE = 'coretemp' 6 | PATH = "/sys/devices/platform/coretemp.0" 7 | PASSIVE = True 8 | -------------------------------------------------------------------------------- /arista/drivers/cpld.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.user.i2c import I2cDevDriver 3 | 4 | class SysCpldI2cDriver(I2cDevDriver): 5 | pass 6 | -------------------------------------------------------------------------------- /arista/drivers/crow.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class CrowFanCpldKernelDriver(I2cKernelDriver): 5 | MODULE = 'crow-fan-driver' 6 | NAME = 'crow_cpld' 7 | -------------------------------------------------------------------------------- /arista/drivers/dpm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/drivers/dpm/__init__.py -------------------------------------------------------------------------------- /arista/drivers/dpm/pmbus.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.log import getLogger 3 | 4 | from ...core.driver.user.i2c import I2cDevDriver 5 | 6 | logging = getLogger(__name__) 7 | 8 | SMBUS_BLOCK_MAX_SZ = 32 9 | 10 | class PmbusUserDriver(I2cDevDriver): 11 | def __init__(self, addr=None, registers=None, **kwargs): 12 | super(PmbusUserDriver, self).__init__(addr=addr, **kwargs) 13 | self.registers = registers 14 | 15 | def getBlock(self, reg): 16 | size = self.read_byte_data(reg) + 1 17 | data = self.read_bytes([reg], size) 18 | return data[1:data[0]+1] 19 | 20 | def setBlock(self, reg, data): 21 | self.write_bytes([reg, len(data)] + data) 22 | -------------------------------------------------------------------------------- /arista/drivers/ds460.py: -------------------------------------------------------------------------------- 1 | from contextlib import closing 2 | 3 | from ..core import utils 4 | from ..core.log import getLogger 5 | 6 | from .pmbus import PmbusKernelDriver 7 | 8 | logging = getLogger(__name__) 9 | 10 | class Ds460KernelDriver(PmbusKernelDriver): 11 | 12 | NAME = 'dps460' 13 | 14 | def setup(self): 15 | addr = self.addr.address 16 | 17 | logging.debug('%s: initializing registers', self.name) 18 | with closing(utils.SMBus(self.addr.bus)) as bus: 19 | for _ in utils.Retrying(interval=10.0, delay=0.5): 20 | try: 21 | bus.read_byte_data(addr, 0x00) 22 | logging.debug('%s: device accessible: bus=%s', 23 | self.name, self.addr.bus) 24 | break 25 | except IOError: 26 | logging.debug('%s: device not accessible; retrying...', self.name) 27 | else: 28 | logging.error('%s: failed to access device: bus=%s', 29 | self.name, self.addr.bus) 30 | return 31 | 32 | try: 33 | byte = bus.read_byte_data(addr, 0x10) 34 | bus.write_byte_data(addr, 0x10, 0) 35 | bus.write_byte_data(addr, 0x03, 1) 36 | bus.write_byte_data(addr, 0x10, byte) 37 | except IOError: 38 | logging.debug('%s: failed to initialize', self.name) 39 | 40 | super(Ds460KernelDriver, self).setup() 41 | -------------------------------------------------------------------------------- /arista/drivers/eeprom.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | 4 | from ..core.utils import inSimulation 5 | from ..libs.wait import waitFor 6 | 7 | from ..core.driver.kernel.i2c import I2cKernelDriver 8 | 9 | class EepromKernelDriver(I2cKernelDriver): 10 | MODULE = 'eeprom' 11 | NAME = 'eeprom' 12 | 13 | def eepromPath(self): 14 | return os.path.join(self.getSysfsPath(), 'eeprom') 15 | 16 | def read(self, size=-1): 17 | with open(self.eepromPath(), 'rb') as f: 18 | return bytearray(f.read(size)) 19 | 20 | def setup(self): 21 | super(EepromKernelDriver, self).setup() 22 | if not inSimulation(): 23 | waitFor(lambda: os.path.exists(self.eepromPath()), 24 | description="eeprom sysfs entry") 25 | 26 | class At24KernelDriver(EepromKernelDriver): 27 | MODULE = 'at24' 28 | 29 | class At24C32KernelDriver(At24KernelDriver): 30 | NAME = '24c32' 31 | 32 | class At24C64KernelDriver(At24KernelDriver): 33 | NAME = '24c64' 34 | 35 | class At24C512KernelDriver(At24KernelDriver): 36 | NAME = '24c512' 37 | -------------------------------------------------------------------------------- /arista/drivers/k10temp.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.pci import PciKernelDriver 3 | 4 | class K10TempKernelDriver(PciKernelDriver): 5 | MODULE = 'k10temp' 6 | PASSIVE = True 7 | -------------------------------------------------------------------------------- /arista/drivers/lm73.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class Lm73KernelDriver(I2cKernelDriver): 5 | MODULE = 'lm73' 6 | NAME = 'lm73' 7 | -------------------------------------------------------------------------------- /arista/drivers/lm75.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class Lm75KernelDriver(I2cKernelDriver): 5 | MODULE = 'lm75' 6 | NAME = 'lm75' 7 | 8 | class Tmp75KernelDriver(Lm75KernelDriver): 9 | NAME = 'tmp75' 10 | -------------------------------------------------------------------------------- /arista/drivers/max31790.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class Max31790KernelDriver(I2cKernelDriver): 5 | MODULE = 'amax31790' 6 | NAME = None 7 | -------------------------------------------------------------------------------- /arista/drivers/max6581.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class Max6581KernelDriver(I2cKernelDriver): 5 | MODULE = 'max6697' 6 | NAME = 'max6581' 7 | -------------------------------------------------------------------------------- /arista/drivers/max6658.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class Max6658KernelDriver(I2cKernelDriver): 5 | MODULE = 'lm90' 6 | NAME = 'max6658' 7 | -------------------------------------------------------------------------------- /arista/drivers/max6697.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class Max6697KernelDriver(I2cKernelDriver): 5 | MODULE = 'max6697' 6 | NAME = 'max6697' 7 | -------------------------------------------------------------------------------- /arista/drivers/minke.py: -------------------------------------------------------------------------------- 1 | from ..core.driver.kernel.i2c import I2cKernelDriver 2 | 3 | class MinkeFanCpldKernelDriver(I2cKernelDriver): 4 | MODULE = 'minke-fan-cpld' 5 | NAME = 'minke_cpld' 6 | -------------------------------------------------------------------------------- /arista/drivers/pali.py: -------------------------------------------------------------------------------- 1 | from ..core.driver.kernel.i2c import I2cKernelDriver 2 | 3 | class Pali2FanCpldKernelDriver(I2cKernelDriver): 4 | MODULE = 'pali-fan-cpld' 5 | NAME = 'pali2_cpld' 6 | -------------------------------------------------------------------------------- /arista/drivers/pch.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.pci import PciKernelDriver 3 | 4 | class PchTempKernelDriver(PciKernelDriver): 5 | MODULE = 'intel_pch_thermal' 6 | PASSIVE = True 7 | 8 | def getHwmonPath(self): 9 | # NOTE: there is no direct link from device to hwmon folder 10 | # path expectation is therefore hardcoded 11 | return '/sys/devices/virtual/thermal/thermal_zone0/hwmon0' 12 | -------------------------------------------------------------------------------- /arista/drivers/raven.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel import KernelDriver 3 | 4 | class RavenFanKernelDriver(KernelDriver): 5 | MODULE = 'raven-fan-driver' 6 | PATH = '/sys/devices/platform/sb800-fans' 7 | -------------------------------------------------------------------------------- /arista/drivers/rook.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | from ..core.driver.kernel.sysfs import LedRgbSysfsImpl 4 | 5 | class RookStatusLedKernelDriver(I2cKernelDriver): 6 | MODULE = 'rook-led-driver' 7 | NAME = 'rook_leds' 8 | 9 | def getLed(self, desc, **kwargs): 10 | return LedRgbSysfsImpl(self, desc, prefix=self.NAME, **kwargs) 11 | 12 | class RookFanCpldKernelDriver(I2cKernelDriver): 13 | MODULE = 'rook-fan-cpld' 14 | 15 | class LaFanCpldKernelDriver(RookFanCpldKernelDriver): 16 | NAME = 'la_cpld' 17 | 18 | class TehamaFanCpldKernelDriver(RookFanCpldKernelDriver): 19 | NAME = 'tehama_cpld' 20 | -------------------------------------------------------------------------------- /arista/drivers/scd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/drivers/scd/__init__.py -------------------------------------------------------------------------------- /arista/drivers/scd/programmable.py: -------------------------------------------------------------------------------- 1 | 2 | from ...inventory.programmable import Programmable 3 | 4 | class ScdProgrammable(Programmable): 5 | def __init__(self, scd): 6 | self.scd = scd 7 | 8 | def getComponent(self): 9 | return self.scd 10 | 11 | def getDescription(self): 12 | return 'System Control Device' 13 | 14 | def getVersion(self): 15 | return self.scd.getVersion() 16 | -------------------------------------------------------------------------------- /arista/drivers/scd/seu.py: -------------------------------------------------------------------------------- 1 | 2 | from ...inventory.seu import SeuReporter 3 | 4 | class ScdSeuReporter(SeuReporter): 5 | def __init__(self, scd, regmap): 6 | self.scd = scd 7 | self.regmap = regmap 8 | self.regs_ = None 9 | 10 | def __str__(self): 11 | return self.__class__.__name__ 12 | 13 | @property 14 | def regs(self): 15 | if self.regs_ is None: 16 | self.regs_ = self.regmap(self.scd.driver) 17 | return self.regs_ 18 | 19 | def getComponent(self): 20 | return self.scd 21 | 22 | def hasSeuError(self): 23 | return bool(self.regs.hasSeuError()) 24 | 25 | def powerCycleOnSeu(self, on=None): 26 | if not hasattr(self.regs, 'powerCycleOnSeu'): 27 | return False 28 | return bool(self.regs.powerCycleOnSeu(value=on)) 29 | -------------------------------------------------------------------------------- /arista/drivers/scd/sram.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | 3 | class SramContent(object): 4 | def __init__(self, size=255, dataSize=4): 5 | self.dataSize_ = dataSize 6 | self.size_ = size 7 | self.content_ = [[0] * self.dataSize_ for _ in range(size)] 8 | 9 | def write(self, addr, value): 10 | externalIndex = addr // self.dataSize_ 11 | internalIndex = addr % self.dataSize_ 12 | if externalIndex >= self.size_: 13 | return False 14 | self.content_[externalIndex][internalIndex] = value 15 | return True 16 | 17 | def __iter__(self): 18 | return iter(self.content_) 19 | -------------------------------------------------------------------------------- /arista/drivers/tmp468.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.driver.kernel.i2c import I2cKernelDriver 3 | 4 | class Tmp468KernelDriver(I2cKernelDriver): 5 | MODULE = 'tmp468' 6 | NAME = 'tmp468' 7 | 8 | class Tmp464KernelDriver(Tmp468KernelDriver): 9 | NAME = 'tmp464' 10 | -------------------------------------------------------------------------------- /arista/drivers/vrm/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.driver.user.i2c import I2cDevDriver 3 | 4 | class VrmI2cUserDriver(I2cDevDriver): 5 | 6 | IDENTIFY_SEQUENCE = [] 7 | 8 | def _expect_read_word(self, reg, value): 9 | try: 10 | data = self.read_word_data(reg) 11 | return data == value 12 | except IOError: 13 | return False 14 | 15 | def _expect_fail_read_word(self, reg): 16 | try: 17 | self.read_word_data(reg) 18 | return False 19 | except IOError: 20 | return True 21 | 22 | def _identify(self, sequence): 23 | for reg, value in sequence: 24 | if value is None: 25 | if not self._expect_fail_read_word(reg): 26 | return False 27 | else: 28 | if not self._expect_read_word(reg, value): 29 | return False 30 | return True 31 | 32 | def identify(self): 33 | if isinstance(self.IDENTIFY_SEQUENCE, tuple): 34 | for seq in self.IDENTIFY_SEQUENCE: 35 | if self._identify(seq): 36 | return True 37 | return False 38 | return self._identify(self.IDENTIFY_SEQUENCE) 39 | 40 | -------------------------------------------------------------------------------- /arista/drivers/vrm/sic450.py: -------------------------------------------------------------------------------- 1 | 2 | from . import VrmI2cUserDriver 3 | 4 | class Sic450UserDriver(VrmI2cUserDriver): 5 | IDENTIFY_SEQUENCE = [ 6 | (0xad, 0x0002), 7 | ] 8 | -------------------------------------------------------------------------------- /arista/drivers/vrm/tps549d22.py: -------------------------------------------------------------------------------- 1 | 2 | from . import VrmI2cUserDriver 3 | 4 | class Tps549D22UserDriver(VrmI2cUserDriver): 5 | IDENTIFY_SEQUENCE = [ 6 | (0xfc, 0x0201), 7 | (0xad, None), 8 | ] 9 | -------------------------------------------------------------------------------- /arista/drivers/xcvr.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..core.driver.kernel.i2c import I2cKernelDriver 4 | from ..core.utils import inSimulation 5 | 6 | class XcvrKernelDriver(I2cKernelDriver): 7 | MODULE = 'optoe' 8 | 9 | def __init__(self, portName=None, **kwargs): 10 | super(XcvrKernelDriver, self).__init__(**kwargs) 11 | self.portName = portName 12 | 13 | def setup(self): 14 | super(XcvrKernelDriver, self).setup() 15 | 16 | if inSimulation(): 17 | return 18 | 19 | self.setPortName(self.portName) 20 | 21 | def setPortName(self, name): 22 | portNamePath = os.path.join(self.getSysfsPath(), 'port_name') 23 | with open(portNamePath, 'w') as f: 24 | f.write(name) 25 | 26 | def setWriteMax(self, size): 27 | writeMaxPath = os.path.join(self.getSysfsPath(), 'write_max') 28 | if os.path.exists(writeMaxPath): 29 | with open(writeMaxPath, 'w') as f: 30 | f.write(str(size)) 31 | 32 | def getWriteMax(self): 33 | writeMaxPath = os.path.join(self.getSysfsPath(), 'write_max') 34 | if not os.path.exists(writeMaxPath): 35 | return 1 # NOTE: previous version of the driver hardcoded 1 36 | with open(writeMaxPath) as f: 37 | return int(f.read()) 38 | 39 | class CmisEepromKernelDriver(XcvrKernelDriver): 40 | NAME = 'optoe3' 41 | 42 | class SfpKernelDriver(XcvrKernelDriver): 43 | NAME = 'optoe2' 44 | 45 | class QsfpKernelDriver(XcvrKernelDriver): 46 | NAME = 'optoe1' 47 | 48 | class OsfpKernelDriver(XcvrKernelDriver): 49 | NAME = 'optoe3' 50 | -------------------------------------------------------------------------------- /arista/inventory/gpio.py: -------------------------------------------------------------------------------- 1 | from . import InventoryInterface, diagcls, diagmethod 2 | 3 | @diagcls 4 | class Gpio(InventoryInterface): 5 | @diagmethod('name') 6 | def getName(self): 7 | raise NotImplementedError 8 | 9 | @diagmethod('addr', fmt=hex) 10 | def getAddr(self): 11 | raise NotImplementedError 12 | 13 | @diagmethod('path') 14 | def getPath(self): 15 | raise NotImplementedError 16 | 17 | @diagmethod('bit') 18 | def getBit(self): 19 | raise NotImplementedError 20 | 21 | @diagmethod('ro') 22 | def isRo(self): 23 | raise NotImplementedError 24 | 25 | @diagmethod('activeLow') 26 | def isActiveLow(self): 27 | raise NotImplementedError 28 | 29 | @diagmethod('rawValue', io=True) 30 | def getRawValue(self): 31 | raise NotImplementedError 32 | 33 | def setRawValue(self, value): 34 | raise NotImplementedError 35 | 36 | @diagmethod('active', io=True) 37 | def isActive(self): 38 | raise NotImplementedError 39 | 40 | def setActive(self, value): 41 | raise NotImplementedError 42 | -------------------------------------------------------------------------------- /arista/inventory/interrupt.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Interrupt(InventoryInterface): 6 | # TODO: get ? 7 | 8 | def set(self): 9 | raise NotImplementedError() 10 | 11 | def clear(self): 12 | raise NotImplementedError() 13 | 14 | @diagmethod('name') 15 | def getName(self): 16 | raise NotImplementedError() 17 | 18 | @diagmethod('file') 19 | def getFile(self): 20 | raise NotImplementedError() 21 | -------------------------------------------------------------------------------- /arista/inventory/led.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Led(InventoryInterface): 6 | @diagmethod('name') 7 | def getName(self): 8 | raise NotImplementedError 9 | 10 | @diagmethod('color', io=True) 11 | def getColor(self): 12 | raise NotImplementedError 13 | 14 | def setColor(self, color): 15 | raise NotImplementedError 16 | 17 | @diagmethod('isStatus') 18 | def isStatusLed(self): 19 | raise NotImplementedError 20 | -------------------------------------------------------------------------------- /arista/inventory/phy.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Phy(InventoryInterface): 6 | @diagmethod('reset', diag=True) 7 | def getReset(self): 8 | raise NotImplementedError 9 | -------------------------------------------------------------------------------- /arista/inventory/powercycle.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface 3 | 4 | class PowerCycle(InventoryInterface): 5 | def powerCycle(self): 6 | raise NotImplementedError 7 | -------------------------------------------------------------------------------- /arista/inventory/programmable.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Programmable(InventoryInterface): 6 | @diagmethod('component', fmt=str) 7 | def getComponent(self): 8 | raise NotImplementedError 9 | 10 | @diagmethod('version', io=True) 11 | def getVersion(self): 12 | raise NotImplementedError 13 | 14 | @diagmethod('description') 15 | def getDescription(self): 16 | raise NotImplementedError 17 | -------------------------------------------------------------------------------- /arista/inventory/rail.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Rail(InventoryInterface): 6 | @diagmethod('name') 7 | def getName(self): 8 | raise NotImplementedError 9 | 10 | @diagmethod('power', io=True) 11 | def getPower(self): 12 | raise NotImplementedError 13 | 14 | @diagmethod('current', io=True) 15 | def getCurrent(self): 16 | raise NotImplementedError 17 | 18 | @diagmethod('voltage', io=True) 19 | def getVoltage(self): 20 | raise NotImplementedError 21 | -------------------------------------------------------------------------------- /arista/inventory/reloadcause.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class ReloadCause(InventoryInterface): 6 | @diagmethod('time') 7 | def getTime(self): 8 | raise NotImplementedError 9 | 10 | @diagmethod('cause') 11 | def getCause(self): 12 | raise NotImplementedError 13 | 14 | @diagmethod('score') 15 | def getScore(self): 16 | raise NotImplementedError 17 | 18 | @diagcls 19 | class ReloadCauseProvider(InventoryInterface): 20 | @diagmethod('source') 21 | def getSourceName(self): 22 | raise NotImplementedError 23 | 24 | @diagmethod('causes', diag=True) 25 | def getCauses(self): 26 | raise NotImplementedError 27 | 28 | @diagmethod('extra') 29 | def getExtra(self): 30 | raise NotImplementedError 31 | 32 | @diagmethod('priority') 33 | def getPriority(self): 34 | raise NotImplementedError 35 | 36 | def setRealTimeClock(self): 37 | pass 38 | 39 | @diagmethod('providers', diag=True) 40 | def getRemoteProviders(self): 41 | return [] 42 | -------------------------------------------------------------------------------- /arista/inventory/reset.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Reset(InventoryInterface): 6 | @diagmethod('name') 7 | def getName(self): 8 | raise NotImplementedError 9 | 10 | @diagmethod('value', io=True) 11 | def read(self): 12 | raise NotImplementedError 13 | 14 | def resetIn(self): 15 | raise NotImplementedError 16 | 17 | def resetOut(self): 18 | raise NotImplementedError 19 | -------------------------------------------------------------------------------- /arista/inventory/seu.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class SeuReporter(InventoryInterface): 6 | @diagmethod('component', fmt=str) 7 | def getComponent(self): 8 | raise NotImplementedError 9 | 10 | @diagmethod('seu') 11 | def hasSeuError(self): 12 | raise NotImplementedError 13 | 14 | @diagmethod('powercycle') 15 | def powerCycleOnSeu(self, on=None): 16 | raise NotImplementedError 17 | -------------------------------------------------------------------------------- /arista/inventory/slot.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Slot(InventoryInterface): 6 | @diagmethod('present', io=True) 7 | def getPresence(self): 8 | raise NotImplementedError 9 | -------------------------------------------------------------------------------- /arista/inventory/temp.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Temp(InventoryInterface): 6 | @diagmethod('name') 7 | def getName(self): 8 | raise NotImplementedError 9 | 10 | def getDesc(self): 11 | raise NotImplementedError 12 | 13 | @diagmethod('present') 14 | def getPresence(self): 15 | raise NotImplementedError 16 | 17 | @diagmethod('model') 18 | def getModel(self): 19 | raise NotImplementedError 20 | 21 | @diagmethod('status', io=True) 22 | def getStatus(self): 23 | raise NotImplementedError 24 | 25 | @diagmethod('value', io=True) 26 | def getTemperature(self): 27 | raise NotImplementedError 28 | 29 | @diagmethod('lowThresh', io=True) 30 | def getLowThreshold(self): 31 | raise NotImplementedError 32 | 33 | @diagmethod('lowCritThresh', io=True) 34 | def getLowCriticalThreshold(self): 35 | raise NotImplementedError 36 | 37 | @diagmethod('highThresh', io=True) 38 | def getHighThreshold(self): 39 | raise NotImplementedError 40 | 41 | @diagmethod('highCritThresh', io=True) 42 | def getHighCriticalThreshold(self): 43 | raise NotImplementedError 44 | 45 | def setLowThreshold(self, value): 46 | raise NotImplementedError 47 | 48 | def setLowCriticalThreshold(self, value): 49 | raise NotImplementedError 50 | 51 | def setHighThreshold(self, value): 52 | raise NotImplementedError 53 | 54 | def setHighCriticalThreshold(self, value): 55 | raise NotImplementedError 56 | 57 | def refreshHardwareThresholds(self): 58 | raise NotImplementedError 59 | -------------------------------------------------------------------------------- /arista/inventory/watchdog.py: -------------------------------------------------------------------------------- 1 | 2 | from . import InventoryInterface, diagcls, diagmethod 3 | 4 | @diagcls 5 | class Watchdog(InventoryInterface): 6 | def arm(self, timeout): 7 | raise NotImplementedError 8 | 9 | def stop(self): 10 | raise NotImplementedError 11 | 12 | @diagmethod('status', io=True) 13 | def status(self): 14 | raise NotImplementedError 15 | -------------------------------------------------------------------------------- /arista/libs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/libs/__init__.py -------------------------------------------------------------------------------- /arista/libs/benchmark.py: -------------------------------------------------------------------------------- 1 | 2 | import contextlib 3 | import time 4 | 5 | from ..core.log import getLogger 6 | 7 | logging = getLogger(__name__) 8 | 9 | @contextlib.contextmanager 10 | def timeit(message): 11 | begin = time.time() 12 | try: 13 | yield 14 | finally: 15 | end = time.time() 16 | logging.debug('%s (took %s seconds)', message, end - begin) 17 | -------------------------------------------------------------------------------- /arista/libs/config.py: -------------------------------------------------------------------------------- 1 | 2 | def parseKeyValueConfig(path, keysep='=', commentchr='#'): 3 | data = {} 4 | with open(path) as f: 5 | for line in f.readlines(): 6 | line = line.rstrip() 7 | if not line or line.startswith(commentchr): 8 | continue 9 | k, v = line.split(keysep, 1) 10 | data[k] = v 11 | return data 12 | -------------------------------------------------------------------------------- /arista/libs/date.py: -------------------------------------------------------------------------------- 1 | 2 | import datetime 3 | 4 | DATE_FORMAT = "%Y-%m-%d %H:%M:%S" 5 | 6 | def datetimeToStr(dt, fmt=DATE_FORMAT): 7 | return dt.strftime(fmt) 8 | 9 | def strToDatetime(s, fmt=DATE_FORMAT): 10 | return datetime.datetime.strptime(s, fmt) 11 | 12 | def epochToDatetime(epoch): 13 | return datetime.datetime.fromtimestamp(epoch) 14 | -------------------------------------------------------------------------------- /arista/libs/fs.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | 4 | def readFileContent(path): 5 | with open(path) as f: 6 | return f.read() 7 | 8 | def touch(path, mode=0o644, times=None): 9 | try: 10 | with open(path, 'a'): 11 | pass 12 | os.chmod(path, mode) 13 | os.utime(path, times) 14 | except IOError: 15 | return False 16 | return True 17 | 18 | def rmfile(path, raises=False): 19 | try: 20 | os.remove(path) 21 | except (OSError, IOError): 22 | if raises: 23 | raise 24 | -------------------------------------------------------------------------------- /arista/libs/i2c.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | from collections import OrderedDict 4 | 5 | _i2cBuses = OrderedDict() 6 | def getKernelI2cBuses(force=False): 7 | if _i2cBuses and not force: 8 | return _i2cBuses 9 | _i2cBuses.clear() 10 | buses = {} 11 | root = '/sys/class/i2c-adapter' 12 | for busName in sorted(os.listdir(root), key=lambda x: int(x[4:])): 13 | busId = int(busName.replace('i2c-', '')) 14 | with open(os.path.join(root, busName, 'name')) as f: 15 | buses[busId] = f.read().rstrip() 16 | return buses 17 | 18 | def i2cBusFromName(name, idx=0, force=False): 19 | buses = getKernelI2cBuses(force=force) 20 | for busId, busName in buses.items(): 21 | if name == busName: 22 | if idx > 0: 23 | idx -= 1 24 | else: 25 | return busId 26 | return None 27 | 28 | -------------------------------------------------------------------------------- /arista/libs/integer.py: -------------------------------------------------------------------------------- 1 | 2 | def iterBits(n): 3 | while n: 4 | yield n & 0x1 5 | n >>= 1 6 | 7 | def listToIntLsb(l): 8 | value = 0 9 | for i, v in enumerate(l): 10 | value |= v << (i * 8) 11 | return value 12 | -------------------------------------------------------------------------------- /arista/libs/onie.py: -------------------------------------------------------------------------------- 1 | 2 | from .config import parseKeyValueConfig 3 | 4 | from ..core.config import flashPath 5 | 6 | machineConfigDict = {} 7 | def getMachineConfigDict(path=flashPath('machine.conf')): 8 | global machineConfigDict 9 | 10 | if machineConfigDict: 11 | return machineConfigDict 12 | 13 | data = {k.split('_', 1)[1] : v for k, v in parseKeyValueConfig(path).items()} 14 | machineConfigDict = data 15 | return data 16 | -------------------------------------------------------------------------------- /arista/libs/ping.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import subprocess 4 | 5 | def ping(address): 6 | cmd = ['ping', '-c', '1', '-W', '1', address] 7 | try: 8 | with open(os.devnull, 'wb') as devnull: 9 | return subprocess.call(cmd, stdout=devnull, stderr=devnull) == 0 10 | except subprocess.CalledProcessError: 11 | return False 12 | -------------------------------------------------------------------------------- /arista/libs/procfs.py: -------------------------------------------------------------------------------- 1 | 2 | import datetime 3 | import os 4 | import time 5 | 6 | from .fs import readFileContent 7 | 8 | from ..core.log import getLogger 9 | 10 | logging = getLogger(__name__) 11 | 12 | def uptime(path='/proc/uptime'): 13 | '''Read uptime from /proc/uptime''' 14 | try: 15 | return tuple(float(v) for v in readFileContent(path).rstrip().split()) 16 | except IOError: 17 | # NOTE: This codepath should only be reached during testing in environments 18 | # where the procfs is not reachable. 19 | return (float(time.time()), float(time.time())) 20 | 21 | def bootDatetime(): 22 | '''Read uptime and return a datetime object representing boot time''' 23 | return datetime.datetime.now() - datetime.timedelta(seconds=uptime()[0]) 24 | 25 | cmdlineDict = {} 26 | def getCmdlineDict(path='/proc/cmdline'): 27 | global cmdlineDict # pylint: disable=global-statement 28 | 29 | if cmdlineDict: 30 | return cmdlineDict 31 | 32 | data = {} 33 | 34 | # The machine running the pytest may not have this path, or permission 35 | try: 36 | with open(path, encoding='utf8') as f: 37 | for entry in f.read().split(): 38 | idx = entry.find('=') 39 | if idx == -1: 40 | data[entry] = None 41 | else: 42 | data[entry[:idx]] = entry[idx+1:] 43 | except IOError: 44 | logging.error("%s is not available, the Arista library may not work properly.", 45 | path) 46 | 47 | cmdlineDict = data 48 | return data 49 | 50 | def inKdump(path='/proc/vmcore'): 51 | return os.path.exists(path) 52 | -------------------------------------------------------------------------------- /arista/libs/pyshell.py: -------------------------------------------------------------------------------- 1 | 2 | def pyshell(): 3 | import pdb 4 | pdb.set_trace() 5 | # TODO: better default shell than pdb 6 | # TODO: use ipython shell if available 7 | -------------------------------------------------------------------------------- /arista/libs/python.py: -------------------------------------------------------------------------------- 1 | 2 | import errno 3 | import os 4 | import sys 5 | import time 6 | 7 | if sys.version_info.major == 2: 8 | PY_VERSION = 2 9 | def isinteger(value): 10 | return isinstance(value, (int, long)) 11 | 12 | def monotonicRaw(): 13 | return time.time() 14 | 15 | def makedirs(path, mode=0o777, exist_ok=False): 16 | try: 17 | os.makedirs(path, mode=mode) 18 | except OSError as e: 19 | if not exist_ok or e.errno != errno.EEXIST: 20 | raise 21 | 22 | else: 23 | PY_VERSION = 3 24 | def isinteger(value): 25 | return isinstance(value, int) 26 | 27 | def monotonicRaw(): 28 | return time.clock_gettime(time.CLOCK_MONOTONIC_RAW) 29 | 30 | makedirs = os.makedirs 31 | -------------------------------------------------------------------------------- /arista/libs/retry.py: -------------------------------------------------------------------------------- 1 | 2 | import time 3 | 4 | def tryGet(func, default=None): 5 | try: 6 | return func() 7 | except Exception: # pylint: disable=broad-except 8 | return default 9 | 10 | def retryGet(func, default=None, retries=1, wait=1., before=False): 11 | for i in range(retries + 1): 12 | if before and wait: 13 | time.sleep(wait) 14 | 15 | try: 16 | return func() 17 | except Exception: # pylint: disable=broad-except 18 | pass 19 | 20 | if not before and wait and i < retries - 1: 21 | time.sleep(wait) 22 | 23 | return default 24 | -------------------------------------------------------------------------------- /arista/platforms/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core import platform 3 | 4 | __all__ = platform.manager.loadPlatforms(__package__) 5 | -------------------------------------------------------------------------------- /arista/platforms/chassis/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/platforms/chassis/__init__.py -------------------------------------------------------------------------------- /arista/platforms/chassis/camp.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.platform import registerPlatform 3 | 4 | from ...components.denali.chassis import DenaliChassis 5 | 6 | @registerPlatform() 7 | class Camp(DenaliChassis): 8 | SID = [] 9 | SKU = ['DCS-7804-CH'] 10 | 11 | NUM_LINECARDS = 4 12 | NUM_FABRICS = 6 13 | NUM_FANS = 24 14 | NUM_PSUS = 8 15 | -------------------------------------------------------------------------------- /arista/platforms/chassis/maunakea.py: -------------------------------------------------------------------------------- 1 | from ...components.pali import Pali2 2 | 3 | from ...core.fixed import FixedChassis 4 | 5 | class MaunaKea2(FixedChassis): 6 | 7 | FAN_COUNT = 4 8 | 9 | @classmethod 10 | def addFanboard(cls, parent, bus): 11 | return Pali2(parent, bus) 12 | -------------------------------------------------------------------------------- /arista/platforms/chassis/northface.py: -------------------------------------------------------------------------------- 1 | 2 | from ...core.platform import registerPlatform 3 | 4 | from ...components.denali.chassis import DenaliChassis 5 | 6 | @registerPlatform() 7 | class NorthFace(DenaliChassis): 8 | SID = [] 9 | SKU = ['DCS-7808-CH'] 10 | 11 | NUM_LINECARDS = 8 12 | NUM_FABRICS = 6 13 | NUM_FANS = 48 14 | NUM_PSUS = 12 15 | -------------------------------------------------------------------------------- /arista/platforms/chassis/tuba.py: -------------------------------------------------------------------------------- 1 | from ...core.fixed import FixedChassis 2 | 3 | class Tuba(FixedChassis): 4 | FAN_SLOTS = 4 5 | FAN_COUNT = 1 6 | HEIGHT_RU = 2 -------------------------------------------------------------------------------- /arista/platforms/chassis/yuba.py: -------------------------------------------------------------------------------- 1 | from ...core.fixed import FixedChassis 2 | 3 | class Yuba(FixedChassis): 4 | FAN_SLOTS = 3 5 | FAN_COUNT = 2 6 | HEIGHT_RU = 1 -------------------------------------------------------------------------------- /arista/platforms/cpu/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/platforms/cpu/__init__.py -------------------------------------------------------------------------------- /arista/platforms/fabric/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/platforms/fabric/__init__.py -------------------------------------------------------------------------------- /arista/platforms/linecard/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/platforms/linecard/__init__.py -------------------------------------------------------------------------------- /arista/platforms/mineral.py: -------------------------------------------------------------------------------- 1 | from ..core.platform import registerPlatform 2 | from ..core.port import PortLayout 3 | from ..core.utils import incrange 4 | 5 | from ..components.psu.delta import DPS495CB, DPS750AB 6 | from ..components.lm73 import Lm73 7 | 8 | from ..descs.sensor import Position, SensorDesc 9 | from ..descs.xcvr import Qsfp28, Sfp 10 | 11 | from .alhambra import Alhambra 12 | 13 | @registerPlatform() 14 | class Mineral(Alhambra): 15 | 16 | SID = ['Mineral', 'MineralSsd'] 17 | SKU = ['DCS-7170-32C', 'DCS-7170-32C-M'] 18 | 19 | PORTS = PortLayout( 20 | (Qsfp28(i, leds=4) for i in incrange(1, 32)), 21 | (Sfp(i) for i in incrange(33, 34)), 22 | ) 23 | 24 | def __init__(self): 25 | super(Mineral, self).__init__(hasLmSensor=False, hasCpuLeds=False, psus=[ 26 | DPS495CB, 27 | DPS750AB, 28 | ]) 29 | self.scd.newComponent(Lm73, self.scd.i2cAddr(7, 0x4a), sensors=[ 30 | SensorDesc(diode=0, name='Front-panel temp sensor', 31 | position=Position.OTHER, target=55, overheat=75, critical=85), 32 | ]) 33 | 34 | @registerPlatform() 35 | class MineralD(Mineral): 36 | 37 | SID = ['MineralD'] 38 | SKU = ['DCS-7170-32CD'] 39 | -------------------------------------------------------------------------------- /arista/platforms/quicksilverr.py: -------------------------------------------------------------------------------- 1 | from ..core.platform import registerPlatform 2 | from ..core.port import PortLayout 3 | from ..core.quirk import PciConfigQuirk 4 | from ..core.utils import incrange 5 | from ..descs.xcvr import Osfp, Sfp 6 | from .cpu.redstart import RedstartCpu 7 | from .quicksilver import QuicksilverBase 8 | class QuicksilverRedstartBase(QuicksilverBase): 9 | SKU = [] 10 | CPU_CLS = RedstartCpu 11 | def __init__(self): 12 | super().__init__() 13 | asicBridgeAddr = self.asic.addr.port.upstream.addr 14 | self.asic.quirks = [ 15 | PciConfigQuirk(asicBridgeAddr, 'CAP_EXP+0x30.W=0x3', 16 | 'Force pcie link speed to Gen 3'), 17 | PciConfigQuirk(asicBridgeAddr, 'CAP_EXP+0x10.W=0x6', 18 | 'Trigger pcie link retraining'), 19 | ] 20 | @registerPlatform() 21 | class QuicksilverP512(QuicksilverRedstartBase): 22 | SID = [ 23 | 'Redstart8Mk2QuicksilverP512', 24 | 'Redstart8Mk2NQuicksilverP512', 25 | 'Redstart832Mk2QuicksilverP512', 26 | 'Redstart832Mk2NQuicksilverP512', 27 | ] 28 | PORTS = PortLayout( 29 | (Osfp(i) for i in incrange(1, 64)), 30 | (Sfp(i) for i in incrange(65, 66)), 31 | ) 32 | HAS_TH5_EXT_DIODE = False 33 | -------------------------------------------------------------------------------- /arista/platforms/supervisor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/platforms/supervisor/__init__.py -------------------------------------------------------------------------------- /arista/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/tests/__init__.py -------------------------------------------------------------------------------- /arista/tests/logging.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | import logging 4 | import sys 5 | 6 | def getLogger(name): 7 | logger = logging.getLogger(name) 8 | logger.setLevel(logging.DEBUG) 9 | logOut = logging.StreamHandler(sys.stdout) 10 | logOut.setFormatter(logging.Formatter('%(asctime)-15s %(levelname)s: ' 11 | '%(message)s')) 12 | logOut.setLevel(logging.DEBUG) 13 | logger.addHandler(logOut) 14 | logger.propagate = 0 15 | return logger 16 | -------------------------------------------------------------------------------- /arista/tests/selftest.py: -------------------------------------------------------------------------------- 1 | 2 | from ..core.log import getLogger 3 | 4 | import unittest 5 | 6 | logger = getLogger( __name__ ) 7 | 8 | def allTests(): 9 | import setuptools 10 | suite = unittest.TestSuite() 11 | for path in setuptools.findall( 'arista' ): 12 | if '/tests/' in path and '__init__.py' not in path and path.endswith( '.py' ): 13 | module = path[ : -3 ].replace( '/', '.' ) 14 | logger.info( 'test-suite: adding %s', module ) 15 | suite.addTests( unittest.defaultTestLoader.loadTestsFromName( module ) ) 16 | return suite 17 | -------------------------------------------------------------------------------- /arista/tests/testing.py: -------------------------------------------------------------------------------- 1 | 2 | import re 3 | import unittest 4 | 5 | try: 6 | from unittest import mock 7 | except ImportError: 8 | import mock 9 | 10 | patch = mock.patch 11 | 12 | # these methods only exist in modern versions of python 13 | if not hasattr( unittest.TestCase, 'assertRegex' ): 14 | def assertRegex( self, string, regex, **kwargs ): 15 | self.assertIsNotNone( re.search( regex, string ), **kwargs ) 16 | setattr( unittest.TestCase, 'assertRegex', assertRegex ) 17 | 18 | def assertNotRegex( self, string, regex, **kwargs ): 19 | self.assertIsNone( re.search( regex, string ), **kwargs ) 20 | setattr( unittest.TestCase, 'assertNotRegex', assertNotRegex ) 21 | -------------------------------------------------------------------------------- /arista/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/utils/__init__.py -------------------------------------------------------------------------------- /arista/utils/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/utils/rpc/__init__.py -------------------------------------------------------------------------------- /arista/utils/rpc/constants.py: -------------------------------------------------------------------------------- 1 | from enum import IntEnum 2 | 3 | class JsonRpcError(IntEnum): 4 | """Error codes defined by the JSON-RPC specification.""" 5 | PARSE_ERROR = -32700 6 | INVALID_REQUEST = -32600 7 | METHOD_NOT_FOUND = -32601 8 | INVALID_PARAMS = -32602 9 | INTERNAL_ERROR = -32603 10 | 11 | JSONRPC_VERSION = '2.0' 12 | -------------------------------------------------------------------------------- /arista/utils/rpc/context.py: -------------------------------------------------------------------------------- 1 | 2 | class ClientContext(): 3 | def __init__(self, peer): 4 | self.addr = peer[0] if peer is not None else None 5 | self.port = peer[1] if peer is not None else None 6 | 7 | def __str__(self): 8 | return f'{self.addr}:{self.port}' 9 | 10 | def slotId(self): 11 | data = self.addr.split('.') 12 | if len(data) == 1: # NOTE: IPv6 detected, not supported 13 | return None 14 | if data[0] != '127' or data[1] != '100' or data[3] != '1': 15 | return None 16 | return int(data[2]) 17 | 18 | def localhost(self): 19 | return self.addr == '127.0.0.1' 20 | -------------------------------------------------------------------------------- /arista/utils/rpc/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/utils/rpc/tests/__init__.py -------------------------------------------------------------------------------- /arista/utils/sonic_platform/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aristanetworks/sonic/01d530033826b8b38c9004c6e95dcf6d88ccdcb3/arista/utils/sonic_platform/__init__.py -------------------------------------------------------------------------------- /arista/utils/sonic_platform/common.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | try: 4 | from arista.core.config import Config 5 | from arista.utils.rpc.client import RpcClient 6 | except ImportError as e: 7 | raise ImportError("%s - Required module not found" % e) 8 | 9 | _globalRpcClient = None 10 | 11 | class RpcClientSource(Enum): 12 | FROM_SUPERVISOR = 1 13 | FROM_LINECARD = 2 14 | 15 | def getGlobalRpcClient(source): 16 | global _globalRpcClient 17 | if _globalRpcClient is None: 18 | host = ( Config().api_rpc_sup if source is RpcClientSource.FROM_LINECARD 19 | else Config().api_rpc_host ) 20 | _globalRpcClient = RpcClient(host, Config().api_rpc_port) 21 | return _globalRpcClient 22 | -------------------------------------------------------------------------------- /arista/utils/sonic_platform/eeprom.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | try: 6 | from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder 7 | except ImportError as e: 8 | raise ImportError("%s - required module not found" % e) 9 | 10 | class Eeprom(TlvInfoDecoder): 11 | """ 12 | Platform-specific Eeprom class 13 | """ 14 | 15 | def __init__(self, prefdl, **kwargs): 16 | TlvInfoDecoder.__init__(self, path=None, start=0, status='', 17 | ro=True, **kwargs) 18 | self._prefdl = prefdl 19 | 20 | def read_eeprom(self): 21 | return self._prefdl 22 | 23 | def set_eeprom(self, e, cmd_args): 24 | raise NotImplementedError 25 | 26 | def decode_eeprom(self, e): 27 | return e.show() 28 | 29 | def is_checksum_valid(self, e): 30 | return (e.isCrcValid(), e.getCrc()) 31 | 32 | def serial_number_str(self, e): 33 | return e.getField('SerialNumber') 34 | 35 | def base_mac_addr(self, e): 36 | return e.getField('MAC') 37 | 38 | def get_eeprom_dict(self, e): 39 | return {'Data': e.toDict()} 40 | 41 | def modelstr(self, e): 42 | return e.getField('SKU') 43 | 44 | def visit_eeprom(self, e, visitor): 45 | visitor.visit_header(None, None, None) 46 | for (code, name, value) in e.toList(): 47 | visitor.visit_tlv(name, code, len(value), value) 48 | visitor.visit_end(e) 49 | 50 | -------------------------------------------------------------------------------- /arista/utils/sonic_platform/platform.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | 5 | try: 6 | from sonic_platform_base.platform_base import PlatformBase 7 | import arista.platforms 8 | from arista.core.log import setupLogging 9 | from arista.core.platform import getPlatform 10 | from arista.utils.sonic_platform.chassis import Chassis 11 | except ImportError as e: 12 | raise ImportError("%s - required module not found" % e) 13 | 14 | def _maybeEnableTracing(): 15 | tracing = os.getenv('ARTRACE') 16 | if tracing is None: 17 | return 18 | # pylint: disable=import-outside-toplevel 19 | setupLogging(tracing) 20 | 21 | class Platform(PlatformBase): 22 | 23 | # NOTE: this cache is necessary since it's possible for some daemon or their 24 | # dependencies to load the platform api multiple time. 25 | # to avoid having different instances of the same platform API in a 26 | # same daemon, the platform object is reused on subsequent invokations. 27 | PLATFORM_CACHE = {} 28 | 29 | def __init__(self): 30 | PlatformBase.__init__(self) 31 | platform = getPlatform() 32 | uid = platform.__class__.__name__ 33 | pcache = Platform.PLATFORM_CACHE.get(uid) 34 | if pcache is not None: 35 | self._platform = pcache._platform 36 | self._chassis = pcache._chassis 37 | else: 38 | self._platform = platform 39 | self._chassis = Chassis(self._platform) 40 | Platform.PLATFORM_CACHE[uid] = self 41 | 42 | _maybeEnableTracing() 43 | -------------------------------------------------------------------------------- /arista/utils/sonic_platform/thermal_manager.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | try: 6 | from arista.core.config import Config 7 | from arista.utils.sonic_platform.thermal_action import * 8 | from arista.utils.sonic_platform.thermal_condition import * 9 | from arista.utils.sonic_platform.thermal_info import * 10 | from sonic_platform_base.sonic_thermal_control.thermal_manager_base \ 11 | import ThermalManagerBase 12 | except ImportError as e: 13 | raise ImportError("%s - required module not found" % e) 14 | 15 | class ThermalManager(ThermalManagerBase): 16 | """ 17 | Manager for controlling thermal policies. 18 | """ 19 | # override default interval of 60 by 10 20 | _interval = Config().cooling_loop_interval 21 | -------------------------------------------------------------------------------- /arista/utils/sonic_platform/watchdog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from __future__ import print_function 4 | 5 | try: 6 | from sonic_platform_base.watchdog_base import WatchdogBase 7 | except ImportError as e: 8 | raise ImportError("%s - required module not found" % e) 9 | 10 | class Watchdog(WatchdogBase): 11 | """ 12 | Platform-specific watchdog class for interfacing with a hardware watchdog module 13 | """ 14 | 15 | def __init__(self, watchdog): 16 | self._watchdog = watchdog 17 | 18 | def get_name(self): 19 | return "watchdog" 20 | 21 | def get_model(self): 22 | return "N/A" 23 | 24 | def get_presence(self): 25 | return True 26 | 27 | def get_serial(self): 28 | return "N/A" 29 | 30 | def get_status(self): 31 | return True 32 | 33 | def get_position_in_parent(self): 34 | return -1 35 | 36 | def is_replaceable(self): 37 | return False 38 | 39 | def arm(self, seconds): 40 | if not self._watchdog.arm(seconds * 100): 41 | return -1 42 | return seconds 43 | 44 | def disarm(self): 45 | return self._watchdog.stop() 46 | 47 | def get_remaining_time(self): 48 | remainingTime = self._watchdog.status()['remainingTime'] 49 | if remainingTime != -1: 50 | remainingTime //= 100 51 | return remainingTime 52 | 53 | def is_armed(self): 54 | return self._watchdog.status()['enabled'] 55 | -------------------------------------------------------------------------------- /arista/utils/sonic_psu.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from .sonic_utils import getInventory 4 | 5 | from .. import platforms # pylint: disable=unused-import 6 | from ..core import platform 7 | from ..core.supervisor import Supervisor 8 | 9 | try: 10 | from sonic_psu.psu_base import PsuBase 11 | except ImportError as e: 12 | raise ImportError("%s - required module not found" % str(e)) 13 | 14 | def getPsuUtil(): 15 | inventory = getInventory() 16 | 17 | class PsuUtil(PsuBase): 18 | """Platform-specific PsuUtil class""" 19 | 20 | def _get_psu(self, index): 21 | if inventory.getNumPsuSlots(): 22 | if 0 <= index < inventory.getNumPsuSlots(): 23 | return inventory.getPsuSlot(index) 24 | else: 25 | if 0 <= index < inventory.getNumPsus(): 26 | return inventory.getPsu(index) 27 | return None 28 | 29 | def get_psu_presence(self, index): 30 | psu = self._get_psu(index - 1) 31 | return psu.getPresence() if psu else False 32 | 33 | def get_psu_status(self, index): 34 | psu = self._get_psu(index - 1) 35 | return psu.getStatus() if psu else False 36 | 37 | def get_num_psus(self): 38 | if isinstance(platform.getPlatform(), Supervisor): 39 | return platform.getPlatform().getChassis().NUM_PSUS 40 | return inventory.getNumPsuSlots() or inventory.getNumPsus() 41 | 42 | return PsuUtil 43 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | sonic-platform-arista (1.0) unstable; urgency=medium 2 | 3 | * Initial release 4 | 5 | -- Samuel Angebault Mon, 24 Nov 2016 11:11:11 -0800 6 | 7 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: sonic-platform-arista 2 | Section: main 3 | Priority: extra 4 | Maintainer: Samuel Angebault 5 | Build-Depends: 6 | dh-python, 7 | debhelper (>= 9.0.0), 8 | python3(>=3.5), 9 | python3-setuptools, 10 | bzip2 11 | Standards-Version: 1.0.0 12 | X-Python3-Version: >= 3.5 13 | XS-Python3-Version: >= 3.5 14 | 15 | Package: drivers-sonic-platform-arista 16 | Architecture: amd64 17 | Depends: 18 | ${misc:Depends}, 19 | linux-image-4.19.0-6-amd64-unsigned 20 | Description: Arista kernel modules for arista platform devices such as fan, led, sfp, psu 21 | 22 | Package: python3-sonic-platform-arista 23 | Architecture: all 24 | Depends: 25 | ${python3:Depends}, 26 | ${misc:Depends} 27 | python3-smbus 28 | Description: Arista python3 libraries 29 | These libraries allow to work with devices such as fan, led, sfp, psu 30 | 31 | Package: sonic-platform-arista 32 | Architecture: amd64 33 | Depends: 34 | ${python3:Depends}, 35 | ${misc:Depends}, 36 | python3-sonic-platform-arista, 37 | python3(>=3.5), 38 | i2c-tools 39 | Description: Miscellaneous Arista scripts and tools 40 | 41 | Package: sonic-platform-arista-libs 42 | Architecture: amd64 43 | Depends: 44 | ${misc:Depends} 45 | Description: Arista compiled user libraries 46 | 47 | Package: drivers-sonic-platform-arista-dev 48 | Architecture: amd64 49 | Depends: 50 | ${misc:Depends} 51 | Description: Miscellaneous Arista headers and symvers files 52 | -------------------------------------------------------------------------------- /debug-dump/arista-debug-helpers.sh: -------------------------------------------------------------------------------- 1 | runcmd() { 2 | echo ":: BEGIN CMD: $@" 3 | "$@" 4 | echo ":: END CMD: $@" 5 | } 6 | 7 | dumpfile() { 8 | local filename="$1" 9 | echo ":: BEGIN FILE: $filename" 10 | cat "$filename" 11 | if [ "$(tail -c 1 "$filename")" != "\n" ]; then 12 | echo 13 | fi 14 | echo ":: END FILE: $filename" 15 | } 16 | -------------------------------------------------------------------------------- /debug-dump/arista.cache: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $(dirname "$0")/arista-debug-helpers.sh 4 | 5 | for cachefile in $(find /run/platform_cache/arista -type f); do 6 | dumpfile $cachefile 7 | done 8 | 9 | dumpfile /etc/sonic/.syseeprom 10 | -------------------------------------------------------------------------------- /debug-dump/arista.dump: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | arista dump 4 | -------------------------------------------------------------------------------- /debug-dump/arista.environment: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $(dirname "$0")/arista-debug-helpers.sh 4 | 5 | runcmd arista show platform environment 6 | runcmd arista show platform power 7 | runcmd arista show linecard environment 8 | runcmd arista show fabric environment 9 | -------------------------------------------------------------------------------- /debug-dump/arista.fs: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $(dirname "$0")/arista-debug-helpers.sh 4 | 5 | runcmd losetup -l 6 | runcmd lsblk -o NAME,LABEL,FSTYPE,FSSIZE,FSUSED,FSAVAIL,SIZE,RO,TYPE,VENDOR,MODEL,SERIAL,ALIGNMENT,MOUNTPOINT 7 | runcmd fdisk -l "/dev/$(lsblk -no pkname "$(df | awk '/\/host$/ {print $1}')")" 8 | -------------------------------------------------------------------------------- /debug-dump/arista.misc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $(dirname "$0")/arista-debug-helpers.sh 4 | 5 | runcmd arista show platform eeprom 6 | runcmd arista show chassis summary 7 | runcmd arista show chassis eeprom 8 | runcmd arista show linecard eeprom 9 | runcmd arista show fabric eeprom 10 | 11 | runcmd arista show linecard status 12 | runcmd arista show fabric status 13 | 14 | runcmd arista show platform xcvr 15 | 16 | dumpfile /proc/scd 17 | 18 | -------------------------------------------------------------------------------- /debug-dump/arista.reboot-cause: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $(dirname "$0")/arista-debug-helpers.sh 4 | 5 | runcmd arista show platform reboot-cause -a -H 6 | runcmd arista show linecard reboot-cause -a -H 7 | 8 | for f in $(find /host/reboot-cause/platform -type f); do 9 | dumpfile "$f" 10 | done 11 | -------------------------------------------------------------------------------- /lib/Makefile: -------------------------------------------------------------------------------- 1 | 2 | MKDIR ?= mkdir 3 | CP ?= cp 4 | 5 | CFLAGS = -fPIC -std=c99 -Wall -Werror -Wextra 6 | #CFLAGS += -DDEBUG -g3 7 | LDFLAGS = -shared 8 | 9 | TARGET = libsfp-eeprom.so 10 | 11 | all: $(TARGET) 12 | 13 | sfp-eeprom.inc: sfp-eeprom-info-c-gen.py 14 | ./sfp-eeprom-info-c-gen.py $@ 15 | 16 | sfp-eeprom.c: sfp-eeprom.inc sfp-eeprom.h 17 | 18 | sfp-eeprom.o: sfp-eeprom.c 19 | 20 | $(TARGET): sfp-eeprom.o 21 | $(CC) $(LDFLAGS) -o $@ $^ 22 | strip $@ 23 | 24 | install:: 25 | $(MKDIR) -p $(DESTDIR) 26 | $(CP) $(TARGET) $(DESTDIR) 27 | 28 | clean:: 29 | $(RM) $(TARGET) sfp-eeprom.inc *.o 30 | -------------------------------------------------------------------------------- /lib/sfp-eeprom.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Arista Networks, Inc. All rights reserved. 2 | 3 | #ifndef SFP_EEPROM_API_H_ 4 | #define SFP_EEPROM_API_H_ 5 | 6 | #include 7 | #include 8 | 9 | typedef uint16_t phyid_t; 10 | 11 | ssize_t read_eeprom( 12 | phyid_t phy_id, /**< physical port ID > **/ 13 | uint16_t offset, /** same format offset as in SONIC Y-Cable read_eeprom */ 14 | uint8_t *value, /**< pointer to a byte array, size is same as len value. */ 15 | uint8_t len /** number of bytes */ 16 | ); 17 | 18 | ssize_t write_eeprom( 19 | phyid_t phy_id, /**< physical port ID > **/ 20 | uint16_t offset, /** same format offset as in SONIC Y-Cable read_eeprom */ 21 | const uint8_t *value, /**< pointer to a byte array, size is same as len value. */ 22 | uint8_t len /** number of bytes */ 23 | ); 24 | 25 | #endif // SFP_EEPROM_API_H_ 26 | -------------------------------------------------------------------------------- /logrotate/arista: -------------------------------------------------------------------------------- 1 | /var/log/arista*.log 2 | { 3 | size 2M 4 | rotate 5 5 | missingok 6 | notifempty 7 | compress 8 | delaycompress 9 | copytruncate 10 | } 11 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | testpaths = arista 3 | python_files = tests/*.py 4 | -------------------------------------------------------------------------------- /scripts/pylint-filter: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import re 4 | import sys 5 | import yaml 6 | 7 | MODULE_RE = re.compile(r'\*{13} Module (.+)') 8 | WARNING_RE = re.compile(r'(?P[^:]+):(?P\d+):(?P\d+):' + 9 | r' (?P[A-Z]\d{4}): .+ \((?P[a-z-]+)\)') 10 | 11 | def print_module_warnings(module, warnings): 12 | print('*' * 13, 'Module', module) 13 | for warning in warnings: 14 | print(warning, end='') 15 | 16 | def main(): 17 | module = None 18 | warnings = [] 19 | excludes = {} 20 | have_unfiltered_warning = False 21 | 22 | with open('.pylint_excludes.yml', 'r', encoding='utf-8') as f: 23 | excludes = yaml.safe_load(f) 24 | 25 | for line in sys.stdin: 26 | m = MODULE_RE.match(line) 27 | if m: 28 | # If we've processed a previous module, output it now. 29 | if module and warnings: 30 | print_module_warnings(module, warnings) 31 | have_unfiltered_warning = True 32 | module = m.group(1) 33 | warnings = [] 34 | continue 35 | 36 | m = WARNING_RE.match(line) 37 | if m: 38 | fn = m.group('filename') 39 | if fn not in excludes or m.group('slug') not in excludes[fn]: 40 | warnings.append(line) 41 | continue 42 | 43 | print(line, end='') 44 | 45 | # Print warnings for the last module 46 | if module and warnings: 47 | print_module_warnings(module, warnings) 48 | 49 | if have_unfiltered_warning: 50 | sys.exit(1) 51 | 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /scripts/pylint-make-excludes: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from collections import defaultdict 4 | import re 5 | import sys 6 | import yaml 7 | from yaml.representer import Representer 8 | 9 | WARNING_RE = re.compile(r'(?P[^:]+):(?P\d+):(?P\d+): ' + 10 | r'(?P[A-Z]\d{4}): .+ \((?P[a-z-]+)\)') 11 | 12 | def main(): 13 | excludes = defaultdict(set) 14 | 15 | for line in sys.stdin: 16 | m = WARNING_RE.match(line) 17 | if m: 18 | excludes[m.group('filename')].add(m.group('slug')) 19 | 20 | with open('.pylint_excludes.yml', 'w', encoding='utf-8') as f: 21 | yaml.add_representer(defaultdict, Representer.represent_dict) 22 | yaml.add_representer(set, 23 | lambda dumper, data: dumper.represent_list(sorted(data))) 24 | yaml.dump(excludes, f) 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /sonic_platform/__init__.py: -------------------------------------------------------------------------------- 1 | # redirect sonic_platform implementation to arista.utils.sonic_platform 2 | # this is essentially a python package symlink 3 | __path__ = [ 4 | __path__[0].replace('sonic_platform', 'arista/utils/sonic_platform') 5 | ] 6 | 7 | # import all modules since some tools expects it 8 | from . import ( 9 | chassis, 10 | component, 11 | fan, 12 | fan_drawer, 13 | module, 14 | pcie, 15 | platform, 16 | psu, 17 | sfp, 18 | thermal, 19 | thermal_manager, 20 | watchdog, 21 | ) 22 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | ccflags-y := -Werror 2 | 3 | ifeq ($(ARISTA_SCD_DRIVER_CONFIG),n) 4 | KBUILD_EXTRA_SYMBOLS += $(EXTRA_SYMBOLS) 5 | else 6 | obj-$(ARISTA_SCD_DRIVER_CONFIG) += scd.o 7 | endif 8 | 9 | obj-m += scd-hwmon.o 10 | scd-hwmon-objs += scd-fan.o 11 | scd-hwmon-objs += scd-gpio.o 12 | scd-hwmon-objs += scd-led.o 13 | scd-hwmon-objs += scd-main.o 14 | scd-hwmon-objs += scd-mdio.o 15 | scd-hwmon-objs += scd-reset.o 16 | scd-hwmon-objs += scd-smbus.o 17 | scd-hwmon-objs += scd-uart.o 18 | scd-hwmon-objs += scd-xcvr.o 19 | # Add module src path as include dir for tracepoints 20 | CFLAGS_scd-smbus.o := -I$M 21 | 22 | obj-m += crow-fan-driver.o 23 | obj-m += raven-fan-driver.o 24 | obj-m += rook-led-driver.o 25 | obj-m += rook-fan-cpld.o 26 | obj-m += tmp468.o 27 | obj-m += amax31790.o 28 | obj-m += pali-fan-cpld.o 29 | obj-m += minke-fan-cpld.o 30 | -------------------------------------------------------------------------------- /src/scd-attrs.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Arista Networks, Inc. 2 | * 3 | * This program is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation; either version 2 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | * 16 | */ 17 | 18 | #ifndef _LINUX_DRIVER_SCD_ATTRS_H_ 19 | #define _LINUX_DRIVER_SCD_ATTRS_H_ 20 | 21 | #define __ATTR_NAME_PTR(_name, _mode, _show, _store) { \ 22 | .attr = { .name = _name, \ 23 | .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \ 24 | .show = _show, \ 25 | .store = _store \ 26 | } 27 | 28 | #define __SENSOR_ATTR_NAME_PTR(_name, _mode, _show, _store, _index) \ 29 | { .dev_attr = __ATTR_NAME_PTR(_name, _mode, _show, _store), \ 30 | .index = _index \ 31 | } 32 | 33 | #endif /* !_LINUX_DRIVER_SCD_ATTRS_H_ */ 34 | -------------------------------------------------------------------------------- /src/scd-led.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Arista Networks, Inc. 2 | * 3 | * This program is free software; you can redistribute it and/or modify 4 | * it under the terms of the GNU General Public License as published by 5 | * the Free Software Foundation; either version 2 of the License, or 6 | * (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program. If not, see . 15 | * 16 | */ 17 | 18 | #ifndef _LINUX_DRIVER_SCD_LED_H_ 19 | #define _LINUX_DRIVER_SCD_LED_H_ 20 | 21 | #include 22 | 23 | struct scd_context; 24 | 25 | #define LED_NAME_MAX_SZ 40 26 | struct scd_led { 27 | struct scd_context *ctx; 28 | struct list_head list; 29 | 30 | u32 addr; 31 | char name[LED_NAME_MAX_SZ]; 32 | struct led_classdev cdev; 33 | }; 34 | 35 | extern int scd_led_add(struct scd_context *ctx, const char *name, u32 addr); 36 | extern void scd_led_remove_all(struct scd_context *ctx); 37 | 38 | #endif /* !_LINUX_DRIVER_SCD_LED_H_ */ 39 | -------------------------------------------------------------------------------- /systemd/platform-arista-chassis-network.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Early network configuration for Arista chassis 3 | Before=database-chassis.service 4 | Before=platform-arista-linecard.service 5 | PartOf=platform-arista.target 6 | ConditionKernelCommandLine=Aboot 7 | ConditionKernelCommandLine=sonic.mode=supervisor 8 | 9 | [Service] 10 | Type=oneshot 11 | RemainAfterExit=true 12 | 13 | ExecStart=/usr/bin/arista-chassis-network start 14 | 15 | [Install] 16 | RequiredBy=platform-arista.target 17 | -------------------------------------------------------------------------------- /systemd/platform-arista-chassis-provision.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Service to provision linecards 3 | Before=platform-arista-linecard.service 4 | After=platform-arista-chassis-network.service 5 | PartOf=platform-arista.target 6 | ConditionKernelCommandLine=Aboot 7 | ConditionKernelCommandLine=sonic.mode=supervisor 8 | 9 | [Service] 10 | Type=simple 11 | ExecStart=/usr/bin/arista-chassis-provision 12 | 13 | [Install] 14 | RequiredBy=platform-arista.target 15 | -------------------------------------------------------------------------------- /systemd/platform-arista-daemon.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Arista platform daemon 3 | After=platform-arista-pmon.service 4 | Requires=platform-arista-pmon.service 5 | PartOf=platform-arista.target 6 | ConditionKernelCommandLine=Aboot 7 | StartLimitIntervalSec=1200 8 | StartLimitBurst=10 9 | 10 | [Service] 11 | Restart=always 12 | RestartSec=30 13 | 14 | ExecStart=/usr/bin/arista -l /var/log/arista-daemon.log --logfile-verbosity '.*/INFO' daemon 15 | 16 | [Install] 17 | RequiredBy=platform-arista.target 18 | -------------------------------------------------------------------------------- /systemd/platform-arista-fabric.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Arista fabric support 3 | Before=syncd@.service 4 | Before=opennsl-modules.service 5 | After=platform-arista-pmon.service 6 | Requires=platform-arista-pmon.service 7 | PartOf=platform-arista.target 8 | ConditionKernelCommandLine=Aboot 9 | ConditionKernelCommandLine=sonic.mode=supervisor 10 | 11 | [Service] 12 | Type=oneshot 13 | RemainAfterExit=true 14 | 15 | ExecStart=/usr/bin/arista -l /var/log/arista-fabric.log fabric --parallel setup --on --powerCycleIfOn 16 | 17 | ExecStop=/usr/bin/arista -l /var/log/arista-fabric.log fabric --parallel clean 18 | 19 | [Install] 20 | RequiredBy=platform-arista.target 21 | -------------------------------------------------------------------------------- /systemd/platform-arista-init-watchdog-start.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Enable the watchdog before platform initialization 3 | Before=platform-arista-swss.service 4 | PartOf=platform-arista.target 5 | ConditionKernelCommandLine=Aboot 6 | ConditionKernelCommandLine=sid=Gardena 7 | 8 | [Service] 9 | Type=oneshot 10 | RemainAfterExit=true 11 | 12 | ExecStart=-/bin/bash -c ' \ 13 | if ! systemctl is-active swss && systemctl is-enabled swss; then \ 14 | timeout=600; \ 15 | echo "Enabling watchdog for $timeout seconds"; \ 16 | /usr/bin/arista watchdog --arm "$timeout"; \ 17 | fi' 18 | 19 | [Install] 20 | RequiredBy=platform-arista.target 21 | -------------------------------------------------------------------------------- /systemd/platform-arista-init-watchdog-stop.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Disable the watchdog after platform initialization 3 | After=swss.service 4 | After=opennsl-modules.service 5 | PartOf=platform-arista.target 6 | ConditionKernelCommandLine=Aboot 7 | ConditionKernelCommandLine=sid=Gardena 8 | 9 | [Service] 10 | Type=oneshot 11 | RemainAfterExit=true 12 | 13 | ExecStart=/usr/bin/arista watchdog --stop 14 | 15 | [Install] 16 | RequiredBy=platform-arista.target 17 | -------------------------------------------------------------------------------- /systemd/platform-arista-linecard-network.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Internal networking configuration for Arista linecards 3 | Before=interfaces-config.service 4 | Before=database.service 5 | PartOf=platform-arista.target 6 | ConditionKernelCommandLine=Aboot 7 | ConditionKernelCommandLine=sonic.mode=linecard 8 | 9 | [Service] 10 | Type=oneshot 11 | RemainAfterExit=true 12 | 13 | ExecStart=-/usr/bin/arista-chassis-network lo 14 | ExecStart=/usr/bin/lc-interface-config 15 | 16 | [Install] 17 | RequiredBy=platform-arista.target 18 | -------------------------------------------------------------------------------- /systemd/platform-arista-linecard.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Arista linecard support 3 | After=platform-arista-fabric.service 4 | Requires=platform-arista-fabric.service 5 | PartOf=platform-arista.target 6 | ConditionKernelCommandLine=Aboot 7 | ConditionKernelCommandLine=sonic.mode=supervisor 8 | 9 | [Service] 10 | Type=oneshot 11 | RemainAfterExit=true 12 | 13 | ExecStart=/usr/bin/arista -l /var/log/arista-linecard.log linecard --parallel setup --lcpu --on --powerCycleIfOn 14 | ExecStop=/usr/bin/arista -l /var/log/arista-linecard.log linecard --parallel clean --lcpu --off 15 | 16 | [Install] 17 | RequiredBy=platform-arista.target 18 | -------------------------------------------------------------------------------- /systemd/platform-arista-pmon.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Arista late platform initialization 3 | After=platform-arista-swss.service 4 | Requires=platform-arista-swss.service 5 | Before=pmon.service system-health.service watchdog-control.service 6 | PartOf=platform-arista.target 7 | ConditionKernelCommandLine=Aboot 8 | 9 | [Service] 10 | Type=oneshot 11 | RemainAfterExit=yes 12 | 13 | ExecStart=/usr/bin/arista -l /var/log/arista.log setup --late 14 | 15 | [Install] 16 | RequiredBy=platform-arista.target 17 | RequiredBy=pmon.service 18 | -------------------------------------------------------------------------------- /systemd/platform-arista-reboot-cause.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Arista reboot cause processing 3 | After=platform-arista-pmon.service 4 | Requires=platform-arista-pmon.service 5 | Before=process-reboot-cause.service determine-reboot-cause.service 6 | PartOf=platform-arista.target 7 | ConditionKernelCommandLine=Aboot 8 | 9 | [Service] 10 | Type=oneshot 11 | RemainAfterExit=true 12 | 13 | ExecStart=/usr/bin/arista -l /var/log/arista.log reboot-cause --process 14 | 15 | [Install] 16 | RequiredBy=platform-arista.target 17 | -------------------------------------------------------------------------------- /systemd/platform-arista-swss.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Arista early platform initialization 3 | After=local-fs.target 4 | Before=opennsl-modules.service 5 | PartOf=platform-arista.target 6 | ConditionKernelCommandLine=Aboot 7 | 8 | [Service] 9 | Type=oneshot 10 | RemainAfterExit=yes 11 | 12 | ExecStart=/usr/bin/arista -l /var/log/arista.log setup --early --reset 13 | ExecStop=/usr/bin/arista -l /var/log/arista.log clean 14 | 15 | [Install] 16 | RequiredBy=platform-arista.target 17 | -------------------------------------------------------------------------------- /systemd/platform-arista.target: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Arista Platform 3 | 4 | [Install] 5 | Alias=sonic-platform-arista.target 6 | WantedBy=multi-user.target 7 | -------------------------------------------------------------------------------- /udev/70-lc-network.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="net",ENV{DEVPATH}=="/devices/pci0000:00/0000:00:03.0/0000:05:00.0/0000:06:*",RUN+="/usr/bin/lc-interface-config $kernel $env{ACTION}" 2 | -------------------------------------------------------------------------------- /udev/98-scd-uio.rules: -------------------------------------------------------------------------------- 1 | # rule to create a uio device name for the scds uio devices, 2 | # name is "/dev/uio+$PCI_ADDRESS+$REG+$INDEX" where 3 | # PCI_ADDRESS is the scd's pci address in DDDD:BB:SS.F format, 4 | # REG is the irq register index on the scd (there can be more than 1 on modular) 5 | # INDEX is the zero-based index of the uio on the scd (the bit) 6 | KERNEL=="uio*", DRIVERS=="scd", SYMLINK+="%s{name}" 7 | -------------------------------------------------------------------------------- /utils/arista: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | 5 | from arista.cli import main 6 | 7 | if __name__ == '__main__': 8 | sys.exit(main(sys.argv[1:])) 9 | --------------------------------------------------------------------------------