feat(ota): include device SKU in update requests (#1429)

* feat(ota): include device SKU in update requests

Read /etc/jetkvm-sku at startup and pass the value as a sku query
parameter when checking for OTA updates, enabling the cloud API to
serve variant-specific firmware for jetkvm-v2 (eMMC) and
jetkvm-v2-sdmmc hardware. Falls back to "jetkvm-v2" when the file
is absent for backwards compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ota): include SKU in auto-update loop

The background auto-update loop in main.go also constructs UpdateParams
and was missing the SKU field, so periodic updates would not transmit
the device SKU to the cloud API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lian Duan
2026-04-25 23:36:29 +02:00
committed by GitHub
parent 38bb8c0107
commit eb56468d25
4 changed files with 23 additions and 0 deletions
+15
View File
@@ -80,6 +80,21 @@ func GetDeviceID() string {
return deviceID
}
var deviceSKU string
var deviceSKUOnce sync.Once
func GetDeviceSKU() string {
deviceSKUOnce.Do(func() {
content, err := os.ReadFile("/etc/jetkvm-sku")
if err != nil || strings.TrimSpace(string(content)) == "" {
deviceSKU = "jetkvm-v2"
} else {
deviceSKU = strings.TrimSpace(string(content))
}
})
return deviceSKU
}
func GetDefaultHostname() string {
deviceId := GetDeviceID()
if deviceId == "unknown_device_id" {
+4
View File
@@ -42,6 +42,9 @@ func (s *State) getUpdateURL(params UpdateParams) (string, error, bool) {
query := updateURL.Query()
query.Set("deviceId", params.DeviceID)
query.Set("prerelease", fmt.Sprintf("%v", params.IncludePreRelease))
if params.SKU != "" {
query.Set("sku", params.SKU)
}
// set the custom versions if they are specified
for component, constraint := range params.Components {
@@ -305,6 +308,7 @@ func (s *State) doUpdate(ctx context.Context, params UpdateParams) error {
// UpdateParams represents the parameters for the update
type UpdateParams struct {
DeviceID string `json:"deviceID"`
SKU string `json:"sku"`
Components map[string]string `json:"components"`
IncludePreRelease bool `json:"includePreRelease"`
ResetConfig bool `json:"resetConfig"`
+1
View File
@@ -155,6 +155,7 @@ func Main() {
includePreRelease := config.IncludePreRelease
err = otaState.TryUpdate(context.Background(), ota.UpdateParams{
DeviceID: GetDeviceID(),
SKU: GetDeviceSKU(),
IncludePreRelease: includePreRelease,
})
if err != nil {
+3
View File
@@ -94,6 +94,7 @@ func GetLocalVersion() (systemVersion *semver.Version, appVersion *semver.Versio
func getUpdateStatus(includePreRelease bool) (*ota.UpdateStatus, error) {
updateStatus, err := otaState.GetUpdateStatus(context.Background(), ota.UpdateParams{
DeviceID: GetDeviceID(),
SKU: GetDeviceSKU(),
IncludePreRelease: includePreRelease,
RequestID: uuid.New().String(),
})
@@ -169,6 +170,7 @@ func rpcTryUpdate() error {
func rpcCheckUpdateComponents(params updateParams, includePreRelease bool) (*ota.UpdateStatus, error) {
updateParams := ota.UpdateParams{
DeviceID: GetDeviceID(),
SKU: GetDeviceSKU(),
IncludePreRelease: includePreRelease,
Components: params.Components,
}
@@ -182,6 +184,7 @@ func rpcCheckUpdateComponents(params updateParams, includePreRelease bool) (*ota
func rpcTryUpdateComponents(params updateParams, includePreRelease bool, resetConfig bool) error {
updateParams := ota.UpdateParams{
DeviceID: GetDeviceID(),
SKU: GetDeviceSKU(),
IncludePreRelease: includePreRelease,
ResetConfig: resetConfig,
Components: params.Components,