1616package flasherapi
1717
1818import (
19+ "bufio"
1920 "context"
21+ "io"
2022 "log/slog"
2123 "strings"
2224
2325 "github.com/arduino/arduino-app-cli/pkg/board/remote"
2426)
2527
28+ const R0_IMAGE_VERSION_ID = "20250807-136"
29+
2630// GetOSImageVersion returns the version of the OS image used in the board.
2731// It is used by the AppLab to enforce image version compatibility.
28- func GetOSImageVersion (ctx context.Context , conn remote.RemoteConn ) (string , error ) {
29- const defaultVersion = "20250807-136"
32+ func GetOSImageVersion (ctx context.Context , conn remote.RemoteConn ) string {
3033
31- output , err := conn .GetCmd ( "cat /etc/buildinfo"). Output ( ctx )
34+ f , err := conn .ReadFile ( " /etc/buildinfo" )
3235 if err != nil {
33- return defaultVersion , err
36+ slog .Warn ("Unable to read buildinfo file" , "err" , err , "using_default" , R0_IMAGE_VERSION_ID )
37+ return R0_IMAGE_VERSION_ID
3438 }
39+ defer f .Close ()
3540
36- if version , ok := ParseOSImageVersion ( string ( output ) ); ok {
37- slog .Info ("find OS Image version" , "version" , version )
38- return version , nil
41+ if version , ok := parseOSImageVersion ( f ); ok {
42+ slog .Info ("found OS Image version" , "version" , version )
43+ return version
3944 }
40- slog .Info ("Unable to find OS Image version" , "using default version " , defaultVersion )
41- return defaultVersion , nil
45+ slog .Warn ("Unable to find OS Image version" , "using_default " , R0_IMAGE_VERSION_ID )
46+ return R0_IMAGE_VERSION_ID
4247}
4348
44- func ParseOSImageVersion (buildInfo string ) (string , bool ) {
45- for _ , line := range strings .Split (buildInfo , "\n " ) {
46- line = strings .TrimSpace (line )
49+ func parseOSImageVersion (r io.Reader ) (string , bool ) {
50+ scanner := bufio .NewScanner (r )
51+ for scanner .Scan () {
52+ line := strings .TrimSpace (scanner .Text ())
4753
4854 key , value , ok := strings .Cut (line , "=" )
4955 if ! ok || key != "BUILD_ID" {
5056 continue
5157 }
5258
53- version := strings .Trim (value , " \" ' " )
59+ version := strings .Trim (value , `"' ` )
5460 if version != "" {
5561 return version , true
5662 }
5763 }
64+
65+ if err := scanner .Err (); err != nil {
66+ return "" , false
67+ }
68+
5869 return "" , false
5970}
6071
@@ -64,77 +75,11 @@ type OSImageRelease struct {
6475 Latest bool
6576}
6677
67- func ListAvailableOSImages () []OSImageRelease {
68- return []OSImageRelease {
69- {
70- ID : "20251123-159" ,
71- VersionLabel : "r159 (2025-11-23)" ,
72- Latest : true ,
73- },
74- }
75- }
76-
77- const R0_IMAGE_VERSION_ID = "20250807-136"
78-
7978// Calculates whether user partition preservation is supported,
8079// according to the current and target OS image versions.
8180//
8281// Preservation is supported if both versions are not the R0 image.
83- func IsUserPartitionPreservationSupported (ctx context.Context , conn remote.RemoteConn , targetImageVersion OSImageRelease ) (bool , error ) {
84- currentImageVersion , err := GetOSImageVersion (ctx , conn )
85- if err != nil {
86- return false , err
87- }
88- return ! (targetImageVersion .ID == R0_IMAGE_VERSION_ID || currentImageVersion == R0_IMAGE_VERSION_ID ), err
89- }
90-
91- type FlashStep string
92-
93- const (
94- FlashStepPrecheck FlashStep = "precheck"
95- FlashStepDetection FlashStep = "detection"
96- FlashStepDownloading FlashStep = "downloading"
97- FlashStepExtracting FlashStep = "extracting"
98- FlashStepFlashing FlashStep = "flashing"
99- )
100-
101- type FlashEvent struct {
102- Step FlashStep
103- OverallProgress int // percentage 0-100
104- Message string // log message to show on the UI
105- }
106-
107- func Flash (
108- ctx context.Context , // context to cancel to interrupt the flashing process
109- // conn remote.RemoteConn, // is this required for the flash process?
110- imageVersion OSImageRelease , // OS image version to flash
111- preserveUserPartition bool , // whether to preserve the user partition or not
112- eventCB func (event FlashEvent ), // Callback, sends progress events to the caller
113- ) error {
114- // The disk space check is done before starting the flashing process.
115- return InsufficientDiskSpaceError {
116- RequiredSpaceMB : 2048 ,
117- AvailableSpaceMB : 1024 ,
118- }
119- }
120-
121- // Errors returned by the Flash function above.
122- // Assertions can be done on the caller side to show better error messages.
123-
124- type QDLFlashError struct {
125- Details string
126- Cause error
127- }
128-
129- type DownloadError struct {
130- Details string
131- }
132-
133- type InsufficientDiskSpaceError struct {
134- RequiredSpaceMB int64
135- AvailableSpaceMB int64
136- }
137-
138- func (e InsufficientDiskSpaceError ) Error () string {
139- return "insufficient disk space"
82+ func IsUserPartitionPreservationSupported (ctx context.Context , conn remote.RemoteConn , targetImageVersion OSImageRelease ) bool {
83+ currentImageVersion := GetOSImageVersion (ctx , conn )
84+ return ! (targetImageVersion .ID == R0_IMAGE_VERSION_ID || currentImageVersion == R0_IMAGE_VERSION_ID )
14085}
0 commit comments