Create per-device ZTP firmware symlink from sonic_parameters.version#2427
Open
berendt wants to merge 1 commit into
Open
Create per-device ZTP firmware symlink from sonic_parameters.version#2427berendt wants to merge 1 commit into
berendt wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The extraction of
sonic_parameters.versioninsync_sonicis quite verbose and duplicates the nestedcustom_fieldsaccess logic used forconfig_version; consider using a small helper (or.getchains) to centralise and simplify readingsonic_parametersfields. - In
export_firmware_link, anySONIC_FIRMWARE_IDENTIFIERvalue other thanserial-numbersilently falls back to hostname; it may be worth explicitly validating the setting (e.g. warning on unrecognised values) to make misconfiguration easier to spot.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The extraction of `sonic_parameters.version` in `sync_sonic` is quite verbose and duplicates the nested `custom_fields` access logic used for `config_version`; consider using a small helper (or `.get` chains) to centralise and simplify reading `sonic_parameters` fields.
- In `export_firmware_link`, any `SONIC_FIRMWARE_IDENTIFIER` value other than `serial-number` silently falls back to hostname; it may be worth explicitly validating the setting (e.g. warning on unrecognised values) to make misconfiguration easier to spot.
## Individual Comments
### Comment 1
<location path="osism/settings.py" line_range="80-83" />
<code_context>
+# sonic_parameters.version custom field. The defaults mirror the ansible
+# httpd role and place the links in the same httpd-served directory as the
+# config exports (SONIC_EXPORT_DIR).
+SONIC_FIRMWARE_DIR = os.getenv("SONIC_FIRMWARE_DIR", "/etc/sonic/export")
+SONIC_FIRMWARE_PREFIX = os.getenv(
+ "SONIC_FIRMWARE_PREFIX", "sonic-broadcom-enterprise-base_"
</code_context>
<issue_to_address>
**suggestion:** Avoid duplicating the export directory default by reusing the existing SONIC_EXPORT_DIR setting.
This adds a second path defaulting to `/etc/sonic/export`, while `SONIC_EXPORT_DIR` already represents the canonical export directory. To avoid config drift if only one env var is overridden, derive the firmware directory from the existing setting when the firmware-specific env var is unset:
```python
SONIC_FIRMWARE_DIR = os.getenv("SONIC_FIRMWARE_DIR", SONIC_EXPORT_DIR)
```
This keeps a single source of truth for the base export path unless a separate firmware directory is explicitly configured.
```suggestion
# sonic_parameters.version custom field. The defaults mirror the ansible
# httpd role and place the links in the same httpd-served directory as the
# config exports (SONIC_EXPORT_DIR).
SONIC_FIRMWARE_DIR = os.getenv("SONIC_FIRMWARE_DIR", SONIC_EXPORT_DIR)
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
5d289f1 to
d3af13e
Compare
The ZTP firmware install now uses a dynamic-url built from <prefix><identifier><suffix> (osism/ansible-collection-services#2131), so each switch fetches sonic-broadcom-enterprise-base_<serial>.bin during ZTP. Have sync_sonic create that per-device name as a relative symlink to the version-specific image sonic-broadcom-enterprise-base_<version>.bin, driven by the device's sonic_parameters.version custom field. - Add SONIC_FIRMWARE_DIR/PREFIX/SUFFIX/IDENTIFIER settings mirroring the ansible httpd role defaults; SONIC_FIRMWARE_DIR defaults to the same httpd-served directory as the config exports. - Add export_firmware_link(), reconciling the symlink on every run and skipping devices without a configured version. The target image is provided out of band, so a dangling link until it arrives is expected. - Read sonic_parameters.version in sync_sonic and pass it to the exporter per device; config_db.json and the CONFIG DB VERSION are untouched. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
d3af13e to
3512b96
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for per-device SONiC firmware selection to the
sync soniccommand, matching the ZTPdynamic-urlswitch in osism/ansible-collection-services#2131.That PR changed the ZTP firmware install to a
dynamic-urlbuilt from<prefix><identifier><suffix>(identifierserial-number), so each switch fetchessonic-broadcom-enterprise-base_<serial>.binduring ZTP. For that name to resolve to the right image, a per-serial link to the version-specific image must exist. The serial→version mapping lives in NetBox (sonic_parameters.version), andsync sonicalready writes the per-serial artefacts into the export directory.Changes
settings.py): newSONIC_FIRMWARE_DIR/_PREFIX/_SUFFIX/_IDENTIFIER, mirroring the ansible httpd role defaults.SONIC_FIRMWARE_DIRdefaults to the same httpd-served directory as the config exports (/etc/sonic/export).export_firmware_link()(exporter.py): creates<prefix><serial><suffix>as a relative symlink to<prefix><version><suffix>. Reconciled on every run (missing/stale/wrongly-pointed links are repaired), skips devices without a configured version, and raises on real failures so they surface as a non-zero task rc. The target image is provided out of band (e.g. downloaded by metalbox), so a dangling link until it arrives is expected.sync_sonic(sync.py): readssonic_parameters.versionper device (likehwsku/config_version) and passes it to the exporter.config_db.jsonand the CONFIG DB VERSION are untouched.For the example device (serial
732656X2419308,version: 4.4.2) this produces:Tests
test_exporter.py(identifier/target naming, serial fallback, reconciliation, self-reference guard, error paths).test_sync.py(version → firmware link,Nonewhen absent, rc=1 on failure);patch_sync_depsandmake_deviceextended accordingly.🤖 Generated with Claude Code