Skip to content

Commit

Permalink
feat: async latest tag app check is update available (#170)
Browse files Browse the repository at this point in the history
  • Loading branch information
CorrectRoadH authored Mar 20, 2024
1 parent a9a77a1 commit 7b060cd
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/IceWhaleTech/CasaOS-AppManagement
go 1.21

require (
github.com/bluele/gcache v0.0.2
github.com/deepmap/oapi-codegen v1.12.4
github.com/docker/compose/v2 v2.23.3
github.com/docker/distribution v2.8.2+incompatible
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw=
github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0=
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY=
Expand Down
54 changes: 37 additions & 17 deletions service/compose_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

v1 "github.com/IceWhaleTech/CasaOS-AppManagement/service/v1"
"github.com/bluele/gcache"

"github.com/IceWhaleTech/CasaOS-AppManagement/codegen"
"github.com/IceWhaleTech/CasaOS-AppManagement/common"
Expand Down Expand Up @@ -189,6 +190,11 @@ func (a *ComposeApp) IsUpdateAvailable() bool {
return a.IsUpdateAvailableWith(storeComposeApp)
}

var latestIsUpdateAvailableCache = gcache.New(100).
LRU().
Expiration(1 * time.Hour).
Build()

func (a *ComposeApp) IsUpdateAvailableWith(storeComposeApp *ComposeApp) bool {
storeComposeAppStoreInfo, err := storeComposeApp.StoreInfo(false)
if err != nil || storeComposeAppStoreInfo == nil {
Expand All @@ -208,29 +214,43 @@ func (a *ComposeApp) IsUpdateAvailableWith(storeComposeApp *ComposeApp) bool {

// TODO to async the check for consist with the version tag app
if mainAppTag == "latest" {
// check image digest when tag is latest.
ctx := context.Background()
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
defer cli.Close()
isUpdateAvailable, err := latestIsUpdateAvailableCache.Get(mainAppImage)
if err != nil {
go func() {
// check image digest when tag is latest.
ctx := context.Background()
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
logger.Error("failed to create docker client", zap.Error(err))
}
defer cli.Close()

imageInfo, _, err := cli.ImageInspectWithRaw(ctx, mainAppImage)
imageInfo, _, err := cli.ImageInspectWithRaw(ctx, mainAppImage)

if err != nil {
logger.Error("failed to inspect image", zap.Error(err), zap.String("name", mainAppImage))
latestIsUpdateAvailableCache.Set(mainAppImage, false)
}
match, err := docker.CompareDigest(storeComposeApp.Services[0].Image, imageInfo.RepoDigests)
if err != nil {
logger.Error("failed to compare digest", zap.Error(err), zap.String("name", mainAppImage))
latestIsUpdateAvailableCache.Set(mainAppImage, false)
}
if match {
logger.Info("main app image tag is latest, thus no update available", zap.String("image", mainApp.Image))
latestIsUpdateAvailableCache.Set(mainAppImage, false)
} else {
logger.Info("main app image tag is latest, but digest is different, thus update is available", zap.String("image", mainApp.Image))
latestIsUpdateAvailableCache.Set(mainAppImage, true)
}
}()

if err != nil {
logger.Error("failed to inspect image", zap.Error(err), zap.String("name", mainAppImage))
return false
}
match, err := docker.CompareDigest(storeComposeApp.Services[0].Image, imageInfo.RepoDigests)
if err != nil {
logger.Error("failed to compare digest", zap.Error(err), zap.String("name", mainAppImage))
return false
}
if match {
logger.Info("main app image tag is latest, thus no update available", zap.String("image", mainApp.Image))
return false
} else {
logger.Info("main app image tag is latest, but digest is different, thus update is available", zap.String("image", mainApp.Image))
if isUpdateAvailable.(bool) {
return true
}
return false
}

storeMainApp := storeComposeApp.App(mainAppName)
Expand Down

0 comments on commit 7b060cd

Please sign in to comment.