-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
V1next history log #578
base: v0.10.x
Are you sure you want to change the base?
V1next history log #578
Conversation
Re: "committed" - this would track, in non-dev mode, if installation was attempted but failed in some way - that is, it would be set to 0 in this case and 1 if installation succeeded. The reason for the failure (probably a %Status) would be worth recording as well for a failed installation. |
This comes into the overall lifecycle rework where we flag the phase in which a module reached during install and track the error that occurred as well. For modules in dev mode, can permit resuming install from the failed phase onwards and for non-dev mode, always start from scratch for the module. |
Not sure why 2c240de doesn't work. I have a local registry with modA and modB, where modB depends on modA. When installing modB, IPM will call The change in commit 2c240de is simple. We create a %Persistent history log object, save it in database, and pass the ID to the work unit. In the work unit, we save the success/failure and TimeEnd. However, when calling %Save() from the spawned process, it raises the error |
It appears the lock is created because we're in a transaction. (Tried stepping through the code while monitoring management portal, lock disappears after manually running TCOMMIT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few really minor comments, but I think this is great overall.
<Value>CommandString</Value> | ||
</Value> | ||
</Data> | ||
<DataLocation>^%IPM.General.HistoryD</DataLocation> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this mapped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The data is mapped to each namespace where %IPM package is mapped. Do we want to separate them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, that'll be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify: there are no global mappings for the data but since it is a %
global, will live in IRISSYS? I think its best to have this be a non-% global and can remove Namespace to scope history by namespace (like the rest of IPM).
@isc-tleavitt Currently, the table data is shared among all namespaces where %IPM is mapped. Do we want to separate them? |
I think this is good now, just need @isc-kiyer's review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isc-shuliu This is a great and exhaustive feature! My comments and some questions are up
<parameter name="argument" required="false" description="Argument for `details` command" /> | ||
<example description="Show history of all packages in the current namespace in descending order">history find </example> | ||
<example description="Show history of all packages in the current namespace where command starts with "load"">history find -DCommandString="load*"</example> | ||
<example description="Show history of all packages in the current namespace where start time is later than 2000-01-01 00:00:00">history find -DTimeStart=">2000-01-01 00:00:00"</example> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than using -D modifiers, may be nice to be able to add sub-modifiers and enum for parameters or modifiers. Then for history, can have enum for the action parameter and sub-modifiers tied to different parameter enums. Is a bit extensive and invasive but I think it will be helpful for many other commands.
Happy to talk through design of this
/// Get the history of all installations, uninstalls, and loads in given namespace | ||
/// The filter argument is a multidimensional array with structure | ||
/// filter(columnName) = value | ||
/// Where value can optionally start with >, >=, <, <=, =, <> or contain * to indicate a wildcard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than value starting with such things, perhaps make value a $ListBuild? The possible issue with it starting with that is that the property's value may actually be using one of these symbols.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea, my concern is that It can be cumbersome for users to construct a command string that contains $ListBuild()
s. They would need to do something like
zpm "history find -DTimeStart=" _ $lb(">", "2000-01-01 00:00:00")
And I can't think of a way for it to work in interactive mode:
USER>zpm
=============================================================================
|| Welcome to the Package Manager Shell (ZPM). Version: ||
|| Enter q/quit to exit the shell. Enter ?/help to view available commands ||
|| Current registry https://pm.community.intersystems.com ||
=============================================================================
zpm:USER>history find -DTimeStart=???
This should account for #704 (the pitfalls of being stuck here for a while, while we've been focused on more pressing things...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isc-shuliu another round of comments. Also, worthwhile adding unit tests since this is a brand new feature. Some test cases I can think about:
- simple commands with no modifiers
- commands with valid modifiers
- commands with invalid modifiers
- modules in dev and non-dev mode
- testing all commands (load, install, uninstall)
- filtering
- altering number of history results to keep
- searching per namespace vs globally
- error handling for invalid filtering columns
<Value>CommandString</Value> | ||
</Value> | ||
</Data> | ||
<DataLocation>^%IPM.General.HistoryD</DataLocation> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify: there are no global mappings for the data but since it is a %
global, will live in IRISSYS? I think its best to have this be a non-% global and can remove Namespace to scope history by namespace (like the rest of IPM).
/// Action of this history record. Can be load, install, or uninstall | ||
Property Action As %String(VALUELIST = ",load,install,uninstall") [ Required ]; | ||
|
||
/// Name of the package being loaded/installed/uninstall. This is not necessarily requried. E.g., when loading a nonexistent directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: typo for required
{ | ||
|
||
/// Action of this history record. Can be load, install, or uninstall | ||
Property Action As %String(VALUELIST = ",load,install,uninstall") [ Required ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isc-shuliu What about module actions like compile, activate etc. Are these things we want to log? Or just in general, all commands from the zpm shell?
cc @isc-tleavitt
Property NameSpace As %String [ InitialExpression = {$NAMESPACE}, Required ]; | ||
|
||
/// User who initiated the action | ||
Property UserName As %String [ InitialExpression = {$USERNAME}, Required ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Use %Library.Username
Property Committed As %Boolean [ InitialExpression = 0, Required ]; | ||
|
||
/// The command string that triggered the action | ||
Property CommandString As %String(MAXLEN = 8192) [ Required ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does command string need a maxlen?
/// Where value can optionally start with >, >=, <, <=, =, <> or contain * to indicate a wildcard | ||
ClassMethod GetHistory(ByRef filter, ascend As %Boolean = 0, limit As %Integer = 0, namespace As %String) As %SQL.StatementResult | ||
{ | ||
Set limit = +limit // Coerce to number to prevent SQL injection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use ?
like in where clauses as TOP ?
to prevent SQL injection
/// Output "clause" is the SQL WHERE clause as a string, container zero or more ? placeholders | ||
/// The "varargs" is an array of values to be substituted in the ? placeholders. | ||
/// The "varargs" may already be populated with values, and new values will be appended to it. | ||
ClassMethod ConstructSQLWhere(filter As %String, namespace As %String, Output clause As %String, ByRef varargs As %String) As %Status [ Internal ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: here filter should be ByRef since it a multi-dim array
@@ -1889,6 +1915,19 @@ ClassMethod LoadFromRepo(tDirectoryName, ByRef tParams) [ Internal ] | |||
} | |||
|
|||
ClassMethod Load(ByRef pCommandInfo) [ Internal ] | |||
{ | |||
Set devMode = $Get(pCommandInfo("data", "DeveloperMode"), 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should devMode default be 0? Without -dev flag, it is 0 right?
|
||
#dim log As %IPM.General.History | ||
Set log = ##class(%IPM.General.History).InstallInit(tModuleName) | ||
Set devMode = $Get(tParams("DeveloperMode"), 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no tParams here. Did you mean to write pCommandInfo("data","DeveloperMode")
?
Implement #366
TODO List