-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: update x/upgrade to handle additional instructions #10032
Conversation
// Optional: Upgrade contains additional instructions for the devops or a hypervisor. | ||
// App specific instructions are handled by the `info` attribute. Here we provide | ||
// information such as pre-upgrade or post-upgrade commands. | ||
UpgradeInstructions Upgrade = 6; |
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.
If you think about a better name for this attribute, please share your proposals. I was also thinking about Setup
, Preparation
...
We should not confuse with the Info
field which is already overloaded (both in meaning and usage).
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.
Considering it contains both pre and post upgrade info, UpgradeInstructions
sounds good.
Visit https://dashboard.github.orijtech.com?back=0&pr=10032&remote=false&repo=cosmos%2Fcosmos-sdk to see benchmark details. |
string pre_run = 1; | ||
// If not empty, a shell command to be run by the upgrade manager or a hypervisor after shutting down | ||
// the app and after running a new app. | ||
string post_run = 2; |
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.
Do you know any use case for this? Also how would you deal with the errors on the post upgrade? The application is already running in theory but your post upgrade script fails. What would you do?
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.
One possible use-case is reporting.
But maybe it's not needed. I'm happy to remove it if you think it may confuse people or if it will be abused.
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.
I believe this post-run script can be used for non-critical activities, so we don't need to handle errors. We can use it for removing backups, alerting users etc
// commands. If multiple files are needed, then they should be packed in a gzip archive. | ||
string url = 2; | ||
// Checksum is a sha256 hex encoded checksum of an artifact referenced by the URL. | ||
string checksum = 3; |
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.
As we use go-getter to download the files in cosmovisor, it automatically checks for the checksum from the download url as ./foo.sh?checksum=b7d96c89d09d9e204f5fedc4d5d55b21
. So a seperate checksum property might not be needed
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.
My intention was to make it universal. Proto files should not assume that we are using the go implementation or cosmovisor. We could put the checksum in the URL, but then we would need to explain it in a comment and require it when registering a new proposal.
message UpgradeInstructions { | ||
option (gogoproto.equal) = true; | ||
|
||
// If not empty, a shell command to be run by the upgrade manager or a hypervisor after shutting down |
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.
I think we should be more clear as to the execution environment of these commands:
- which shell? Preferably we wouldn't allow people to write full on shell scripts, but if so we should be clear about this expectation.
- what's the working directory should this be configurable?
- should we provide some way to pass environment variables to commands?
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.
Maybe we can drop "shell" and just say "command"?
It's up to the app developers to make a system requirements.
1a6d03b
to
28d7e80
Compare
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
message Asset { | ||
option (gogoproto.equal) = true; | ||
|
||
// Platform identifier. It's composed from OS and CPU architecture. Example: "linux/amd64" | ||
string platform = 1; | ||
// URL to a script or binary to download. Should be related to the UpgradeInstructions pre_run or post_run | ||
// commands. If multiple files are needed, then they should be packed in a gzip archive. | ||
string url = 2; | ||
// Checksum is a sha256 hex encoded checksum of an artifact referenced by the URL. | ||
string checksum = 3; | ||
} |
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.
With the addition of the pre_run
and post_run
fields, there will be a need to download those as well. By being able to provide a name for assets, users won't be constrained to only providing archives when they need to include a special pre_run
script.
I feel like adding a string name
field to the Asset
is the most versatile solution. We'd state that entries in repeated Asset assets
SHOULD be unique by name
and platform
(as opposed to just platform
).
Alternatively, a hierarchy could be used, but there's a couple ways to do that, either name -> platforms or platform -> names. There's good arguments for either way though. But I feel like leaving it flat allows users to handle it the way that makes the most sense for them.
Cosmovisor Usage
Assets would be downloaded in the order provided but only if there is a Source
entry that matches the system's platform
(or there's a platform
= any
entry for it). Basically, we'd loop through the assets
, if the platform
matches the system, then it's downloaded. Or if the platform
is any
and the name
is one that hasn't yet been downloaded this upgrade, then it'll be downloaded.
If the url
returns an archive, then the name
becomes a directory name. Otherwise it's a filename. Either way, the full path to the downloaded result would be {DAEMON_HOME}/{upgrade name}/{name}
. Sub directories would be allowed in the name
, but we'd need to discuss whether or not to allow it to contain ../
.
I'd make a couple special cases for the name
value:
- If the
name
is empty, and theurl
returns an archive, it is unpacked and becomes{DAEMON_HOME}/{upgrade name}
(similar to current behavior). If thename
is empty and theurl
returns a non-archive file, it'll end up as{DAEMON_HOME}/{upgrade name}/bin/{DAEMON_NAME}
. - If the
name
is.
then theurl
will need to return an archive and it'll be unpacked into{DAEMON_HOME}/{upgrade name}
. If the name is.
and theurl
returns something other than an archive, an error will be given and the upgrade/download process will be interrupted.
We'd probably want to maintain the current functionality where, after doing the downloads, if {DAEMON_HOME}/{upgrade name}/bin/{DAEMON_NAME}
doesn't exist, but {DAEMON_HOME}/{upgrade name}/{DAEMON_NAME}
does, the latter is copied to the former.
// Optional: Upgrade contains additional instructions for the devops or a hypervisor. | ||
// App specific instructions are handled by the `info` attribute. Here we provide | ||
// information such as pre-upgrade or post-upgrade commands. | ||
UpgradeInstructions Upgrade = 6; |
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.
It might actually be desirable to extract the platform
field all the way out to the UpgradeInstructions
message and make the UpgradeInstructions Upgrade
a repeated
field with a comment that it SHOULD have only one entry per platform. This would allow for different pre/post-run commands that can be tailored for specific environments.
Also, in order to help minimize on-chain data, should we throw this in a oneof
and allow a url to be provided in place of the full structure here? The idea is that the url should return the same structure, but really, for chains that don't use Cosmovisor
, it could return whatever they want. If the UpgradeInstructions
are provided directly, they'll be serialized as json and added to the upgrade-info.json
file in the upgrade
field. If a url is provided, that url will be added to the upgrade-info.json
file as upgrade_url
.
Lastly, I feel like this field would be better named instructions
. The proto file is named upgrade.proto
and so is the module for it. The message the field is in is Plan
but is sometimes called an "upgrade plan." The info
field is sometimes called "upgrade info." Basically, the word "upgrade" is already used in a few ways and having a field with that name can easily cause more confusion.
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.
Also, in order to help minimize on-chain data, should we throw this in a oneof and allow a url to be provided in place of the full structure here? The idea is that the url should return the same structure, but really, for chains that don't use Cosmovisor, it could return whatever they want. If the UpgradeInstructions are provided directly, they'll be serialized as json and added to the upgrade-info.json file in the upgrade field. If a url is provided, that url will be added to the upgrade-info.json file as upgrade_url.
I was thinking about this part a bit further with extra consideration for the first upgrade using new definitions.
If we allow the a url in the info
field to return the newly defined UpgradeInstructions
structure (e.g. as JSON), then as long as the nodes are running updated versions of Cosmovisor, an update can be done using these new proto fields without needing the chain software to already be using the new version. Otherwise, these new fields cannot be used for the next upgrade; they can only be used for upgrades after the one that adds these fields to the protos.
The downside is the further overloading of the info
field.
// SHOULD have only one entry per platform. | ||
repeated Asset assets = 3; | ||
// Description contains additional information about the upgrade process. Can reference an external resource. | ||
string description = 4; |
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.
I think we can remove this description
field.
If someone provides UpgradeInstructions
in the Plan
then the info
field can then be used for this. If UpgradeInstructions
aren't included in the Plan
then this field wouldn't be there to populate.
I guess that if the UpgradeInstructions
are included, then the info
field is ignored (as far as automated processing goes).
PR for related DRAFT ADR: #10602 |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Description
Closes: #10047
This is an alternative to solution to the one drafted in #10006
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
!
to the type prefix if API or client breaking changeCHANGELOG.md
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...
!
in the type prefix if API or client breaking change