blob: 3dc9a10da1fb30324ead6d8f7ec01e41dd65e5b5 [file] [log] [blame] [edit]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package version
import (
"context"
"encoding/json"
"fmt"
"os"
lab_platform "go.chromium.org/chromiumos/infra/proto/go/lab_platform"
"go.chromium.org/luci/common/errors"
"go.chromium.org/infra/cros/recovery/models"
)
func readLocalVersion(ctx context.Context, board, model, deviceType string) (Data, error) {
localDir := os.Getenv("DRONE_RECOVERY_VERSIONS_DIR")
if localDir == "" {
return nil, errors.New("read local version: target directory is not defined")
}
return readLocalVersionFile(ctx, localDir, board, model, deviceType)
}
func readLocalVersionFile(ctx context.Context, localDir, board, model, deviceType string) (Data, error) {
if localDir == "" {
return nil, errors.New("read local version file: directory is not provider")
}
if board == "" || model == "" {
return nil, errors.New("read local version file: board or model is empty")
}
svFilePath := fmt.Sprintf("%s/%s-%s.json", localDir, board, model)
svByteArr, err := os.ReadFile(svFilePath)
if err != nil {
return nil, errors.Fmt("read local version file %q: failed to read file: %w", svFilePath, err)
}
rvs := &models.RecoveryVersionList{}
if err := json.Unmarshal(svByteArr, rvs); err != nil {
return nil, errors.Fmt("read local version file %q: failed to unmarshal: %w", svFilePath, err)
}
if len(rvs.Versions) > 0 {
for _, rv := range rvs.Versions {
if rv.GetDeviceType() == deviceType {
return &lab_platform.StableVersion{
Target: &lab_platform.StableVersionTarget{
Board: rv.GetBoard(),
Model: rv.GetModel(),
DeviceType: deviceType,
},
OsVersion: rv.GetOsImage(),
OsImagePath: rv.GetOsImagePath(),
FirmwareRoVersion: rv.GetFwVersion(),
FirmwareRoImagePath: rv.GetFwImage(),
}, nil
}
}
return nil, errors.Fmt("read local version file %q: failed to find version for requested type (%s)", svFilePath, deviceType)
}
// TODO(filipek): remove when old format will be fully deprecated.
// Fall back to the old format, but only for classic.
if deviceType != toDeviceType(CrOSType) {
return nil, errors.Fmt("read local version file %q: failed to find version for requested type", svFilePath)
}
rv := &models.RecoveryVersion{}
if err := json.Unmarshal(svByteArr, rv); err != nil {
return nil, errors.Fmt("read local version file %q: failed to parse: %w", svFilePath, err)
}
return &lab_platform.StableVersion{
Target: &lab_platform.StableVersionTarget{
Board: rv.GetBoard(),
Model: rv.GetModel(),
DeviceType: deviceType,
},
OsVersion: rv.GetOsImage(),
OsImagePath: toOSImagePath(ctx, rv, deviceType),
FirmwareRoVersion: rv.GetFwVersion(),
FirmwareRoImagePath: rv.GetFwImage(),
}, nil
}
func toOSImagePath(ctx context.Context, rv *models.RecoveryVersion, deviceType string) string {
switch ToType(deviceType) {
case CrOSType:
return fmt.Sprintf("%s-release/%s", rv.GetBoard(), rv.GetOsImage())
case AndroidOSType:
return fmt.Sprintf("android-build/build_explorer/artifacts_list/%s/%s-trunk_staging-userdebug/%s-ota-%s.zip", rv.GetOsImage(), rv.GetBoard(), rv.GetBoard(), rv.GetOsImage())
}
return ""
}