Skip to content

Commit 0a91812

Browse files
authored
Update pending versions metadata on check for updates (#5475)
* Update pending versions metadata on check for updates
1 parent a42cceb commit 0a91812

File tree

5 files changed

+90
-21
lines changed

5 files changed

+90
-21
lines changed

pkg/store/kotsstore/version_store.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,24 @@ func (s *KOTSStore) GetCurrentUpdateCursor(appID string, channelID string) (stri
957957
return updateCursor.String, nil
958958
}
959959

960+
func (s *KOTSStore) UpdateAppVersionMetadata(appID string, update upstreamtypes.Update) error {
961+
db := persistence.MustGetDBSession()
962+
963+
query := `UPDATE app_version
964+
SET is_required = ?, version_label = ?, release_notes = ?
965+
WHERE app_id = ? AND channel_id = ? AND update_cursor = ?`
966+
967+
_, err := db.WriteOneParameterized(gorqlite.ParameterizedStatement{
968+
Query: query,
969+
Arguments: []interface{}{update.IsRequired, update.VersionLabel, update.ReleaseNotes, appID, update.ChannelID, update.Cursor},
970+
})
971+
if err != nil {
972+
return fmt.Errorf("update app version metadata: %v", err)
973+
}
974+
975+
return nil
976+
}
977+
960978
func (s *KOTSStore) HasStrictPreflights(appID string, sequence int64) (bool, error) {
961979
var preflightSpecStr gorqlite.NullString
962980
db := persistence.MustGetDBSession()

pkg/store/mock/mock.go

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/store/store_interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ type VersionStore interface {
190190
UpdateNextAppVersionDiffSummary(appID string, baseSequence int64) error
191191
GetNextAppSequence(appID string) (int64, error)
192192
GetCurrentUpdateCursor(appID string, channelID string) (string, error)
193+
UpdateAppVersionMetadata(appID string, update upstreamtypes.Update) error
193194
HasStrictPreflights(appID string, sequence int64) (bool, error)
194195
GetEmbeddedClusterConfigForVersion(appID string, sequence int64) (*embeddedclusterv1beta1.Config, error)
195196
}

pkg/updatechecker/updatechecker.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ func checkForKotsAppUpdates(opts types.CheckForUpdatesOpts, finishedChan chan<-
274274
return nil, errors.Errorf("no app versions found for app %s in downstream %s", opts.AppID, d.ClusterID)
275275
}
276276

277+
if err := maybeUpdatePendingVersionsMetadata(a.ID, getUpdatesOptions, appVersions.CurrentVersion); err != nil {
278+
logger.Error(errors.Wrap(err, "failed to update app version metadata"))
279+
}
280+
277281
filteredUpdates := removeOldUpdates(updates.Updates, appVersions, licenseChan.IsSemverRequired)
278282

279283
var availableReleases []types.UpdateCheckRelease
@@ -333,6 +337,40 @@ func checkForKotsAppUpdates(opts types.CheckForUpdatesOpts, finishedChan chan<-
333337
return &ucr, nil
334338
}
335339

340+
// maybeUpdatePendingVersionsMetadata updates metadata for pending versions since the currently deployed version.
341+
//
342+
// Limitations:
343+
// - Only gets pending releases for the channel of the currently deployed version, even if channel changed in later versions
344+
// - Does not rerender the application archive, so the Installation object in the archive can become out of sync
345+
// - This is not in the critical path - errors are logged but don't fail the overall update check
346+
func maybeUpdatePendingVersionsMetadata(appID string, getUpdatesOptions kotspull.GetUpdatesOptions, currentVersion *downstreamtypes.DownstreamVersion) error {
347+
if currentVersion == nil {
348+
return nil
349+
}
350+
351+
// update options to use info from the currently deployed version
352+
getUpdatesOptions.CurrentCursor = currentVersion.UpdateCursor
353+
getUpdatesOptions.CurrentChannelID = currentVersion.ChannelID
354+
getUpdatesOptions.ChannelChanged = false // we want the api to return pending updates after the currently deployed version even if channel changed in later versions
355+
if currentVersion.KOTSKinds != nil {
356+
getUpdatesOptions.CurrentChannelName = currentVersion.KOTSKinds.Installation.Spec.ChannelName
357+
} else {
358+
getUpdatesOptions.CurrentChannelName = ""
359+
}
360+
361+
updates, err := kotspull.GetUpdates(fmt.Sprintf("replicated://%s", getUpdatesOptions.License.Spec.AppSlug), getUpdatesOptions)
362+
if err != nil {
363+
return errors.Wrap(err, "get updates for metadata refresh")
364+
}
365+
366+
for _, update := range updates.Updates {
367+
if err := store.UpdateAppVersionMetadata(appID, update); err != nil {
368+
logger.Error(errors.Wrapf(err, "failed to update app version metadata for %s", update.VersionLabel))
369+
}
370+
}
371+
return nil
372+
}
373+
336374
func downloadAppUpdates(opts types.CheckForUpdatesOpts, appID string, clusterID string, updates []upstreamtypes.Update, updateCheckTime time.Time) error {
337375
for index, update := range updates {
338376
appSequence, err := upstream.DownloadUpdate(appID, update, opts.SkipPreflights, opts.SkipCompatibilityCheck)

web/src/components/apps/AppVersionHistory.tsx

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ type State = {
122122
loadingVersionHistory: boolean;
123123
logs: Object | null;
124124
logsLoading: boolean;
125-
noUpdateAvailiableText: string;
126125
numOfRemainingVersions: number;
127126
numOfSkippedVersions: number;
128127
pageSize: Number;
@@ -206,7 +205,6 @@ class AppVersionHistory extends Component<Props, State> {
206205
loadingVersionHistory: true,
207206
logs: null,
208207
logsLoading: false,
209-
noUpdateAvailiableText: "",
210208
numOfRemainingVersions: 0,
211209
numOfSkippedVersions: 0,
212210
pageSize: 20,
@@ -992,25 +990,11 @@ class AppVersionHistory extends Component<Props, State> {
992990
const response = await res.json();
993991

994992
if (response.availableUpdates === 0) {
995-
if (
996-
!find(this.state.versionHistory, {
997-
parentSequence: response.currentAppSequence,
998-
})
999-
) {
1000-
// version history list is out of sync - most probably because of automatic updates happening in the background - refetch list
1001-
this.fetchKotsDownstreamHistory();
1002-
this.setState({ checkingForUpdates: false });
1003-
} else {
1004-
this.setState({
1005-
checkingForUpdates: false,
1006-
noUpdateAvailiableText: "There are no updates available",
1007-
});
1008-
setTimeout(() => {
1009-
this.setState({
1010-
noUpdateAvailiableText: "",
1011-
});
1012-
}, 3000);
1013-
}
993+
// refresh version history list as it can be out of sync because of:
994+
// 1. automatic updates happening in the background
995+
// 2. there can be metadata updates to pending versions already in the version history list
996+
this.fetchKotsDownstreamHistory();
997+
this.setState({ checkingForUpdates: false });
1014998
} else {
1015999
this.state.appUpdateChecker.start(this.getAppUpdateStatus, 1000);
10161000
}

0 commit comments

Comments
 (0)