From 890e1f38cce3a21c2bab322006e0b2e02cc92a5c Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 4 Aug 2020 23:51:35 -0700 Subject: [PATCH] [sonic-py-common] get_platform(): Refactor method of retrieving platform identifier (#5094) Applications running in the host OS can read the platform identifier from /host/machine.conf. When loading configuration, sonic-config-engine *needs* to read the platform identifier from machine.conf, as it it responsible for populating the value in Config DB. When an application is running inside a Docker container, the machine.conf file is not accessible, as the /host directory is not mounted. So we need to retrieve the platform identifier from Config DB if get_platform() is called from inside a Docker container. However, we can't simply check that we're running in a Docker container because the host OS of the SONiC virtual switch is running inside a Docker container. So I refactored `get_platform()` to: 1. Read from the `PLATFORM` environment variable if it exists (which is defined in a virtual switch Docker container) 2. Read from machine.conf if possible (works in the host OS of a standard SONiC image, critical for sonic-config-engine at boot) 3. Read the value from Config DB (needed for Docker containers running in SONiC, as machine.conf is not accessible to them) - Also fix typo in daemon_base.py - Also changes to align `get_hwsku()` with `get_platform()` --- platform/vs/docker-sonic-vs/start.sh | 4 +- .../sonic_py_common/daemon_base.py | 2 +- .../sonic_py_common/device_info.py | 41 ++++++++++++++++--- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index f8fcf974b6..fc84ccad69 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -2,8 +2,8 @@ # generate configuration -PLATFORM=x86_64-kvm_x86_64-r0 -HWSKU=Force10-S6000 +export PLATFORM=x86_64-kvm_x86_64-r0 +export HWSKU=Force10-S6000 ln -sf /usr/share/sonic/device/$PLATFORM/$HWSKU /usr/share/sonic/hwsku diff --git a/src/sonic-py-common/sonic_py_common/daemon_base.py b/src/sonic-py-common/sonic_py_common/daemon_base.py index 77188a004f..6a2c6a22d2 100644 --- a/src/sonic-py-common/sonic_py_common/daemon_base.py +++ b/src/sonic-py-common/sonic_py_common/daemon_base.py @@ -56,7 +56,7 @@ class DaemonBase(Logger): platform_util = None # Get path to platform and hwsku - (platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku() + (platform_path, hwsku_path) = device_info.get_paths_to_platform_and_hwsku_dirs() try: module_file = "/".join([platform_path, "plugins", module_name + ".py"]) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index a1645182a8..99f818b0f2 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -58,6 +58,17 @@ def get_platform(): Returns: A string containing the device's platform identifier """ + + # If we are running in a virtual switch Docker container, the environment + # variable 'PLATFORM' will be defined and will contain the platform + # identifier. + platform_env = os.getenv("PLATFORM") + if platform_env: + return platform_env + + # If 'PLATFORM' env variable is not defined, we try to read the platform + # identifier from machine.conf. This is critical for sonic-config-engine, + # because it is responsible for populating this value in Config DB. machine_info = get_machine_info() if machine_info: if 'onie_platform' in machine_info: @@ -65,6 +76,21 @@ def get_platform(): elif 'aboot_platform' in machine_info: return machine_info['aboot_platform'] + # If we fail to read from machine.conf, we may be running inside a Docker + # container in SONiC, where the /host directory is not mounted. In this + # case the value should already be populated in Config DB so we finally + # try reading it from there. + try: + config_db = ConfigDBConnector() + config_db.connect() + + metadata = config_db.get_table('DEVICE_METADATA') + + if 'localhost' in metadata and 'platform' in metadata['localhost']: + return metadata['localhost']['platform'] + except Exception: + pass + return None @@ -75,15 +101,18 @@ def get_hwsku(): Returns: A string containing the device's hardware SKU identifier """ - config_db = ConfigDBConnector() - config_db.connect() + try: + config_db = ConfigDBConnector() + config_db.connect() - metadata = config_db.get_table('DEVICE_METADATA') + metadata = config_db.get_table('DEVICE_METADATA') - if 'localhost' in metadata and 'hwsku' in metadata['localhost']: - return metadata['localhost']['hwsku'] + if 'localhost' in metadata and 'hwsku' in metadata['localhost']: + return metadata['localhost']['hwsku'] + except Exception: + pass - return "" + return None def get_platform_and_hwsku():