fix: remove mutex from updateApp & updateSystem

This commit is contained in:
Siyuan 2025-11-17 13:33:18 +00:00
parent e1943c89e8
commit eff4920a06
5 changed files with 34 additions and 17 deletions

View File

@ -2,25 +2,15 @@ package ota
import ( import (
"context" "context"
"fmt"
"time" "time"
"github.com/rs/zerolog"
) )
const ( const (
appUpdatePath = "/userdata/jetkvm/jetkvm_app.update" appUpdatePath = "/userdata/jetkvm/jetkvm_app.update"
) )
func (s *State) componentUpdateError(prefix string, err error, l *zerolog.Logger) error { // DO NOT call it directly, it's not thread safe
if l == nil { // Mutex is currently held by the caller, e.g. doUpdate
l = s.l
}
l.Error().Err(err).Msg(prefix)
s.error = fmt.Sprintf("%s: %v", prefix, err)
return err
}
func (s *State) updateApp(ctx context.Context, appUpdate *componentUpdateStatus) error { func (s *State) updateApp(ctx context.Context, appUpdate *componentUpdateStatus) error {
l := s.l.With().Str("path", appUpdatePath).Logger() l := s.l.With().Str("path", appUpdatePath).Logger()

View File

@ -1,8 +1,22 @@
package ota package ota
import "errors" import (
"errors"
"fmt"
"github.com/rs/zerolog"
)
var ( var (
// ErrVersionNotFound is returned when the specified version is not found // ErrVersionNotFound is returned when the specified version is not found
ErrVersionNotFound = errors.New("specified version not found") ErrVersionNotFound = errors.New("specified version not found")
) )
func (s *State) componentUpdateError(prefix string, err error, l *zerolog.Logger) error {
if l == nil {
l = s.l
}
l.Error().Err(err).Msg(prefix)
s.error = fmt.Sprintf("%s: %v", prefix, err)
return err
}

View File

@ -171,6 +171,8 @@ func (s *State) doUpdate(ctx context.Context, params UpdateParams) error {
s.triggerComponentUpdateState("system", systemUpdate) s.triggerComponentUpdateState("system", systemUpdate)
} }
scopedLogger.Trace().Bool("pending", appUpdate.pending).Msg("Checking for app update")
if appUpdate.pending { if appUpdate.pending {
scopedLogger.Info(). scopedLogger.Info().
Str("url", appUpdate.url). Str("url", appUpdate.url).
@ -184,6 +186,8 @@ func (s *State) doUpdate(ctx context.Context, params UpdateParams) error {
scopedLogger.Info().Msg("App is up to date") scopedLogger.Info().Msg("App is up to date")
} }
scopedLogger.Trace().Bool("pending", systemUpdate.pending).Msg("Checking for system update")
if systemUpdate.pending { if systemUpdate.pending {
if err := s.updateSystem(ctx, systemUpdate); err != nil { if err := s.updateSystem(ctx, systemUpdate); err != nil {
return s.componentUpdateError("Error updating system", err, &scopedLogger) return s.componentUpdateError("Error updating system", err, &scopedLogger)

View File

@ -11,10 +11,9 @@ const (
systemUpdatePath = "/userdata/jetkvm/update_system.tar" systemUpdatePath = "/userdata/jetkvm/update_system.tar"
) )
// DO NOT call it directly, it's not thread safe
// Mutex is currently held by the caller, e.g. doUpdate
func (s *State) updateSystem(ctx context.Context, systemUpdate *componentUpdateStatus) error { func (s *State) updateSystem(ctx context.Context, systemUpdate *componentUpdateStatus) error {
s.mu.Lock()
defer s.mu.Unlock()
l := s.l.With().Str("path", systemUpdatePath).Logger() l := s.l.With().Str("path", systemUpdatePath).Logger()
if err := s.downloadFile(ctx, systemUpdatePath, systemUpdate.url, "system"); err != nil { if err := s.downloadFile(ctx, systemUpdatePath, systemUpdate.url, "system"); err != nil {

View File

@ -26,6 +26,10 @@ func syncFilesystem() error {
} }
func (s *State) downloadFile(ctx context.Context, path string, url string, component string) error { func (s *State) downloadFile(ctx context.Context, path string, url string, component string) error {
logger := s.l.With().Str("path", path).Str("url", url).Str("component", component).Logger()
logger.Trace().Msg("downloading file")
componentUpdate, ok := s.componentUpdateStatuses[component] componentUpdate, ok := s.componentUpdateStatuses[component]
if !ok { if !ok {
return fmt.Errorf("component %s not found", component) return fmt.Errorf("component %s not found", component)
@ -34,6 +38,7 @@ func (s *State) downloadFile(ctx context.Context, path string, url string, compo
downloadProgress := componentUpdate.downloadProgress downloadProgress := componentUpdate.downloadProgress
if _, err := os.Stat(path); err == nil { if _, err := os.Stat(path); err == nil {
logger.Trace().Msg("removing existing file")
if err := os.Remove(path); err != nil { if err := os.Remove(path); err != nil {
return fmt.Errorf("error removing existing file: %w", err) return fmt.Errorf("error removing existing file: %w", err)
} }
@ -41,23 +46,27 @@ func (s *State) downloadFile(ctx context.Context, path string, url string, compo
unverifiedPath := path + ".unverified" unverifiedPath := path + ".unverified"
if _, err := os.Stat(unverifiedPath); err == nil { if _, err := os.Stat(unverifiedPath); err == nil {
logger.Trace().Msg("removing existing unverified file")
if err := os.Remove(unverifiedPath); err != nil { if err := os.Remove(unverifiedPath); err != nil {
return fmt.Errorf("error removing existing unverified file: %w", err) return fmt.Errorf("error removing existing unverified file: %w", err)
} }
} }
logger.Trace().Msg("creating unverified file")
file, err := os.Create(unverifiedPath) file, err := os.Create(unverifiedPath)
if err != nil { if err != nil {
return fmt.Errorf("error creating file: %w", err) return fmt.Errorf("error creating file: %w", err)
} }
defer file.Close() defer file.Close()
logger.Trace().Msg("creating request")
req, err := http.NewRequestWithContext(ctx, "GET", url, nil) req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil { if err != nil {
return fmt.Errorf("error creating request: %w", err) return fmt.Errorf("error creating request: %w", err)
} }
client := s.client() client := s.client()
logger.Trace().Msg("starting download")
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return fmt.Errorf("error downloading file: %w", err) return fmt.Errorf("error downloading file: %w", err)
@ -100,15 +109,16 @@ func (s *State) downloadFile(ctx context.Context, path string, url string, compo
} }
} }
logger.Trace().Msg("download finished")
file.Close() file.Close()
logger.Trace().Msg("syncing filesystem")
if err := syncFilesystem(); err != nil { if err := syncFilesystem(); err != nil {
return fmt.Errorf("error syncing filesystem: %w", err) return fmt.Errorf("error syncing filesystem: %w", err)
} }
return nil return nil
} }
func (s *State) verifyFile(path string, expectedHash string, verifyProgress *float32) error { func (s *State) verifyFile(path string, expectedHash string, verifyProgress *float32) error {
l := s.l.With().Str("path", path).Logger() l := s.l.With().Str("path", path).Logger()