Skip to content

Commit

Permalink
Adding the HLD for SONiC long reset button press
Browse files Browse the repository at this point in the history
  • Loading branch information
azmyali98 committed Jan 4, 2024
1 parent 2f0e7fd commit a166dfa
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 0 deletions.
277 changes: 277 additions & 0 deletions doc/SONiC_long_reset_button_press_hld.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
# Long reset button press HLD

## Table of contents

- [Revision](#)
- [Scope](#scope)
- [Definitions/Abbreviations](#definitionsabbreviations)
- [Requirements](#requirements-in-this-feature-we-want-to-be-able-to)
- [1 Architecture design](#architecture-design)
- [2 High level design](#high-level-design)
- [3 Performance](#performance)
- [4 Flows](#flows)
- [5 Configuration and management](#configuration-and-management)
- [5.1. CLI](#cli)
- [5.2. YANG Model](#yang-model)
- [6 Warmboot and Fastboot Design Impact](#warmboot-and-fastboot-design-impact)
- [7 Restrictions/Limitations](#restrictionslimitations)
- [8 Testing Requirements/Design](#testing-requirementsdesign)
- [8.1. Unit Test cases](#unit-test-cases)
- [8.2. System Test cases](#system-test-cases)

###

###

###

###

# Revision

| **Rev** | **Date** | **Author** | **Change Description** |
|:---------:|:------------:|:-------------------------------:|:------------------------|
| 1.0 | 17/12/2023 | Azmy Ali (Nvidia SONiC Team) | Initial public version |

###

# Scope

This document describes the design details for supporting long reset button press on a SONiC switch. In this document, we will specify the default behavior
for SONiC OS on long reset button press and the new service intorduced during initializtion flow to handle the functionality applied on long reset button press.

# Definitions/Abbreviations

| **Term** | **Description** |
|-----------------------------|--------------------------------------------------------------------------------------|
| SONiC | Software for Open Networking in the Cloud |
| Long reset button press | Pressing the physical reset button on the switch not less than 15 seconds |
| short reset button press | Pressing the physical reset button on the switch less than 15 seconds |
| CLI | Сommand-line Interface |
| YANG | Yet Another Next Generation |

###

# Requirements Overview

The long reset button press feature implementation shall support the following:

1. On long reboot press, the OS will restore the local users' configurations, by deleting non-default users and restoring default passwords for default users and expiring these passwords due to security conecerns.
2. Each vendor can decide what is the behavior on long reset button press and add his own implementation.
3. On short reset button press, the current init flow should not be affected and should boot normally.
4. Feature should be enabled or diabled by setting compliation flag to true or false.
5. Feature can be disabled and enabled using CLI command.
6. The feature is enabled by default.


###

# Architecture Design

In this feature, we want to add new systemd service ```long-reboot.service``` to the init flow. This new service is expected to run on the system during boot and before any connection is open to the switch which includes SSH and serial connection as well and perform the vendor defined behavior on long reset button press.

![](./sonic_long_reboot.png)

The service is dependent on the ```database.service``` for reading the configured feature state, so it needs to run after it during boot.

###

# High-Level Design

This feature will be a built-in SONiC feature. The default behavior implementation will reside in ```src/sonic-platform-common/sonic_platform_base/long_reboot_press_base.py``` file. The default behavior will delete non-default users and restore the original passwords of the default users and expire them.
The ```long_reboot_press_base.py``` will contain the following class


```
class LongRebootPressBase(object):
"""
Base class for long reboot press on the switch
"""

def start(self):
'''
define the functionality
'''
# the implementation of deleting non-default users adn restoring original passwords for default users and expiring them
```


Each vendor should inherent this class and add the implementation that he desires in this class. In the ```src/sonic-host-services/scripts/long-reboot``` script, that it is being called on ```long-reboot.service``` start, will do import of the inherented class and calls the ```start()``` method of the class as we can see in the following code snippet.


```
def get_platform_long_reboot_press():
try:
from sonic_platform.long_reboot_press import LongRebootPressPlatform
long_reboot_press_class = LongRebootPressPlatform()
except ImportError:
syslog.syslog(syslog.LOG_WARNING, "LongRebootPress: sonic_platform package not installed. Unable to find platform long reboot press implementation")
raise Exception('Long reboot press implementation is not defined')

return long_reboot_press_class

```


The ```LongRebootPressPlatform``` class that each vendor implements should look like this:


```
class LongRebootPressPlatform(LongRebootPressBase):
def start(self):
'''
Vendor specific implementation.
'''
# can inherent the base class implementation
```


The new serivce python script ```src/sonic-host-services/scripts/long-reboot``` will read the feature state from the ```LONG_RESET_BUTTON``` table in ```CONFIG_DB``` database. If feature is enabled and a long reset button press detected, the service will perfom the implementation in the ```start()``` method as we can see in the following code snippet:

```
class LongRebootPress:
def __init__(self):
self.platform_long_reboot_press = get_platform_long_reboot_press()
def get_feature_state(self):
feature_state = 'enabled'
try:
db = ConfigDBConnector()
db.connect(wait_for_init=True, retry_on=True)
feature_info = db.get_table(swsscommon.CFG_LONG_RESET_BUTTON)
feature_state = feature_info.get('feature', {}).get('state')
return True if feature_state == 'enabled' else False
except Exception:
syslog.syslog(syslog.LOG_ERR, "LongRebootPress: Failed to connect to DB")
raise
def start(self):
feature_enabled = self.get_feature_state()
long_reboot_button_press = get_long_reboot_status()
if long_reboot_button_press and feature_enabled:
syslog.syslog(syslog.LOG_INFO, "LongRebootPress: Long reboot detected, the system is resetting passwords to default")
self.platform_long_reboot_press.start()
else:
syslog.syslog(syslog.LOG_INFO, "LongRebootPress: Skipping..")
def main():
LongRebootPress().start()
```

The feature is added to the init flow as long as the we set the ```ENABLE_LONG_RESET_BUTTON_PRESS``` in ```rules/config```

```
# ENABLE_LONG_RESET_BUTTON_PRESS - enable long reset button press on switch
ENABLE_LONG_RESET_BUTTON_PRESS ?= y
```

###

# Performance

The ```long-reboot.service``` is required to run as fast as possible, and it is expected to finish running in milliseconds **(150-300 milliseconds)** on long reset detected, and not delay the init flow more than that.

# Flows

###### Long Reboot Press during init flow
![](./sonic-reboot-press-init-flow.png "Long Reboot Press during init")

The defualt long reset button press functionality is to delete non default users and restore original passwords for default users and expire them, all done using linux commands

# Configuration and management

## CLI

<!-- omit in toc -->
## Command structure

**User interface**:
```
config
\-- long-reset-button-press
|-- state <enabled|disabled>
show
\-- long-reset-button-press
```

### Config command group
**The following command set long-reset-button-press feature state:**
```bash
config long-reset-button-press state <enabled|disabled>
```

### Show command
**The following command display long-reset-button-press configuration:**
```bash
root@sonic:/home/admin# show long-reset-button-press
state
-------
enabled
```

## YANG model
New YANG model `long-reset-button-press.yang` will be added to provide support for configuring long-reset-button-press state.

**Skeleton code:**
```
module sonic-long-reset-button-press {
yang-version 1.1;
namespace "http://github.com/sonic-net/long-reset-button-press";
description "LONG_RESET_BUTTON YANG Module for SONiC-based OS";
revision 2023-05-18 {
description "First Revision";
}
container sonic-long-reset-button-press {
container LONG_RESET_BUTTON {
description "LONG_RESET_BUTTON part of config_db.json";
container STATE {
leaf state {
type string {
pattern "enabled|disabled";
}
description "Long reset button feature state";
default disabled;
}
} /* end of container STATE */
}
/* end of container LONG_RESET_BUTTON */
}
/* end of top level container */
}
/* end of module sonic-long-reset-button-press */
```


# Warmboot and Fastboot Design Impact

The feature will not have any impact on fast reboot or warmboot.

# Restrictions/Limitations

No limitations and restrictions

# Testing Requirements/Design

## Unit Test cases

In unit testing we want to see that the feature control commands change the state in the DB.

## System Test cases

We want to test the following flows:

1. On long reset button press and the feature state is enabled, non-default users are supposed to be deleted and default users are restored to original passwords and expired.
2. On long reset button press and the feature state is disabled, no change the current init flow.
3. short reboot/warm/fast reboot does not affect the current init flow.
Binary file added doc/sonic-reboot-press-init-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/sonic_long_reboot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a166dfa

Please sign in to comment.