@@ -124,13 +124,14 @@ func (s *Store) SetStatus(id int64, status, errMsg, backupPath string) error {
124124func (s * Store ) LatestUpgrade (routerID string ) (* Upgrade , error ) {
125125 var u Upgrade
126126 var finished sql.NullInt64
127+ var errStr , backup sql.NullString
127128 err := s .db .QueryRow (`
128129 SELECT id, router_id, target_version, target_url, checksum, status, error, backup_path, started_at, finished_at
129130 FROM firmware_upgrades
130131 WHERE router_id = ?
131132 ORDER BY started_at DESC
132133 LIMIT 1
133- ` , routerID ).Scan (& u .ID , & u .RouterID , & u .TargetVersion , & u .TargetURL , & u .Checksum , & u .Status , & u . Error , & u . BackupPath , & u .StartedAt , & finished )
134+ ` , routerID ).Scan (& u .ID , & u .RouterID , & u .TargetVersion , & u .TargetURL , & u .Checksum , & u .Status , & errStr , & backup , & u .StartedAt , & finished )
134135 if err == sql .ErrNoRows {
135136 return nil , nil
136137 }
@@ -140,25 +141,54 @@ func (s *Store) LatestUpgrade(routerID string) (*Upgrade, error) {
140141 if finished .Valid {
141142 u .FinishedAt = & finished .Int64
142143 }
144+ if errStr .Valid {
145+ u .Error = errStr .String
146+ }
147+ if backup .Valid {
148+ u .BackupPath = backup .String
149+ }
143150 return & u , nil
144151}
145152
146153// GetUpgradeByID busca un upgrade por ID (para validar propiedad del agente).
147154func (s * Store ) GetUpgradeByID (id int64 ) (* Upgrade , error ) {
148155 var u Upgrade
149156 var finished sql.NullInt64
157+ var errStr , backup sql.NullString
150158 err := s .db .QueryRow (`
151159 SELECT id, router_id, target_version, target_url, checksum, status, error, backup_path, started_at, finished_at
152160 FROM firmware_upgrades WHERE id = ?
153- ` , id ).Scan (& u .ID , & u .RouterID , & u .TargetVersion , & u .TargetURL , & u .Checksum , & u .Status , & u . Error , & u . BackupPath , & u .StartedAt , & finished )
161+ ` , id ).Scan (& u .ID , & u .RouterID , & u .TargetVersion , & u .TargetURL , & u .Checksum , & u .Status , & errStr , & backup , & u .StartedAt , & finished )
154162 if err == sql .ErrNoRows {
155163 return nil , nil
156164 }
157165 if err != nil {
158166 return nil , err
159167 }
168+ if errStr .Valid {
169+ u .Error = errStr .String
170+ }
171+ if backup .Valid {
172+ u .BackupPath = backup .String
173+ }
160174 if finished .Valid {
161175 u .FinishedAt = & finished .Int64
162176 }
163177 return & u , nil
164178}
179+
180+ // DismissLatest borra el último intento de upgrade del router si está
181+ // terminado (failed o done). Un upgrade en curso (requested/running) no se
182+ // toca: el aviso de error obsoleto debe poder descartarse (#519) sin poder
183+ // cancelar una operación viva por accidente.
184+ func (s * Store ) DismissLatest (routerID string ) error {
185+ up , err := s .LatestUpgrade (routerID )
186+ if err != nil {
187+ return err
188+ }
189+ if up == nil || (up .Status != "failed" && up .Status != "done" ) {
190+ return nil
191+ }
192+ _ , err = s .db .Exec (`DELETE FROM firmware_upgrades WHERE id = ?` , up .ID )
193+ return err
194+ }
0 commit comments