Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- #822: The CPF resource processor now supports system expressions and macros in CPF merge files
- #578 Added functionality to record and display IPM history of install, uninstall, load, and update
- #961: Adding creation of a lock file for a module by using the `-create-lockfile` flag on install.
- #992: Implement automatic history purge logic

### Changed
- #316: All parameters, except developer mode, included with a `load`, `install` or `update` command will be propagated to dependencies
Expand Down
38 changes: 38 additions & 0 deletions src/cls/IPM/General/History.cls
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,44 @@ ClassMethod DeleteHistory(ByRef filter) As %Integer
quit rs.%ROWCOUNT
}

/// Automatically purge old history based on retention settings
ClassMethod AutoPurgeOldHistory() As %Status
{
set sc = $$$OK
if ..GetHistoryLastPurge() = +$horolog {
quit sc
}
set retainDays = ##class(%IPM.Repo.UniversalSettings).GetHistoryRetain()
if +retainDays <=0 {
quit sc
}
set cutoffDate = $system.SQL.Functions.DATEADD("d", -retainDays, +$horolog)
set filter("TimeStart") = "<='" _cutoffDate_"'"
try {
set count = ..DeleteHistoryGlobally(.filter, 0)
do ..SetHistoryLastPurge()
} catch ex {
set sc = ex.AsStatus()
}
return sc
}

ClassMethod SetHistoryLastPurge()
{
new $namespace
set index = ##class(%IPM.Repo.UniversalSettings).#HistoryRetain
set $namespace = "%SYS"
set ^IPM.settings(index, "lastPurge") = +$horolog
}

ClassMethod GetHistoryLastPurge() As %String
{
new $namespace
set index = ##class(%IPM.Repo.UniversalSettings).#HistoryRetain
set $namespace = "%SYS"
return $get(^IPM.settings(index, "lastPurge"))
}

ClassMethod DeleteHistoryGlobally(
ByRef filter,
verbose As %Boolean = 0) As %Integer
Expand Down
8 changes: 7 additions & 1 deletion src/cls/IPM/Main.cls
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,9 @@ generate /my/path -export 00000,PacketName2,IgnorePacket2^00000,PacketName3,Igno
<example description="Show only installation history of package &quot;zpip&quot; in all namespaces ">history find -globally -Daction=install -Dpackage=zpip</example>
<example description="Delete all histories in the namespace">history delete -confirm</example>
<example description="Show details of history item with ID 3 and information for each undergone lifecyle phase">history details 3 -phases</example>
<example description="Enable history auto-purge. Example: config set HistoryRetain 30.">config set HistoryRetain "days" </example>
<example description="Disable history auto-purge">config set HistoryRetain 0</example>
<example description="Display the current history retention setting.">config get HistoryRetain</example>
</command>

</commands>
Expand All @@ -807,7 +810,10 @@ ClassMethod Shell(
pTerminateOnError As %Boolean = 0,
pHaltOnComplete As %Boolean = 0) As %Status
{
set tSC = $$$OK
set tSC = ##class(%IPM.General.History).AutoPurgeOldHistory()
if $$$ISERR(tSC) {
return tSC
}
do ..ShellInternal(pCommand,.tException)
if $isobject(tException) {
if pTerminateOnError {
Expand Down
11 changes: 10 additions & 1 deletion src/cls/IPM/Repo/UniversalSettings.cls
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ Parameter UseStandalonePip = "UseStandalonePip";
/// Default value is 0, where 1.0.0-anystring is considered a pre-release of 1.0.0, hence 1.0.0-anystring < 1.0.0
Parameter SemVerPostRelease = "SemVerPostRelease";

Parameter CONFIGURABLE = "trackingId,analytics,ColorScheme,TerminalPrompt,PublishTimeout,PipCaller,UseStandalonePip,SemVerPostRelease,DefaultLogEntryLimit";
/// Configuration setting name used to determine the number of days
/// to retain IPM history records before they are eligible for cleanup.
Parameter HistoryRetain = "history_retain";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: add a comment describing this setting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the comments on top of the parameter


Parameter CONFIGURABLE = "trackingId,analytics,ColorScheme,TerminalPrompt,PublishTimeout,PipCaller,UseStandalonePip,SemVerPostRelease,DefaultLogEntryLimit,HistoryRetain";

/// Returns configArray, that includes all configurable settings
ClassMethod GetAll(Output configArray) As %Status
Expand Down Expand Up @@ -181,4 +185,9 @@ ClassMethod SetAnalyticsAvailable(
return ..SetValue(..#analytics, +val, overwrite)
}

ClassMethod GetHistoryRetain() As %Integer
{
return ..GetValue(..#HistoryRetain)
}

}
28 changes: 26 additions & 2 deletions tests/unit_tests/Test/PM/Unit/CLI.cls
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,11 @@ Method CompareModifiers(
}
}

Method RunCommand(pCommand As %String)
Method RunCommand(pCommand As %String) As %Status
{
do ##class(%IPM.Main).Shell(pCommand)
set status = ##class(%IPM.Main).Shell(pCommand)
do $$$LogMessage("Run command: "_pCommand)
return status
}

Method AssertNoException(pCommand As %String)
Expand Down Expand Up @@ -313,4 +314,27 @@ Method TestListPython() As %Status
quit sc
}

Method TestAutoPurgeOldHistory() As %Status
{
set status = ..RunCommand("config set HistoryRetain 30")
do $$$AssertStatusOK(status, "Config set executed successfully")

set status = ..RunCommand("config get HistoryRetain")
do $$$AssertStatusOK(status, "Config get executed successfully")

do $$$LogMessage("Update HistoryRetain from 30 days to 1 day")
set status = ..RunCommand("config set HistoryRetain 1")
do $$$AssertStatusOK(status, "HistoryRetain is changed from 30 days to 1 day successfully")

do $$$LogMessage("Purging old history entries older than 1 day")
set status = ##class(%IPM.General.History).AutoPurgeOldHistory()
do $$$AssertStatusOK(status, "AutoPurgeOldHistory executed successfully")

set afterPurge = ##class(%IPM.General.History).GetHistoryLastPurge()
do $$$LogMessage("After purge timestamp: "_afterPurge)
do $$$LogMessage("reset set the HistoryRetain to default value by deleting the config")
set status = ..RunCommand("config delete HistoryRetain")
do $$$AssertStatusOK(status, "Config delete executed successfully")
}

}