-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
hard-nett
committed
Mar 19, 2024
1 parent
dfb1cbd
commit 666dbbd
Showing
5 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
scripts/release/create_binaries_json/create_all_binaries_json.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/bin/bash | ||
|
||
tags=( | ||
"v4.2.0" | ||
) | ||
|
||
echo "## Upgrade binaries" | ||
|
||
for tag in ${tags[@]}; do | ||
echo | ||
echo "### ${tag}" | ||
echo | ||
echo '```json' | ||
python create_binaries_json.py --tag $tag | ||
echo '```' | ||
done |
118 changes: 118 additions & 0 deletions
118
scripts/release/create_binaries_json/create_binaries_json.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
""" | ||
Usage: | ||
This script generates a JSON object containing binary download URLs and their corresponding checksums | ||
for a given release tag of terpnetwork/terp-core or from a provided checksum URL. | ||
The binary JSON is compatible with cosmovisor and with the chain registry. | ||
You can run this script with the following commands: | ||
❯ python create_binaries_json.py --checksums_url https://github.com/terpnetwork/terp-core/releases/download/v4.2.0/sha256sum.txt | ||
Output: | ||
{ | ||
"binaries": { | ||
"linux/arm64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-linux-arm64?checksum=<checksum>", | ||
"darwin/arm64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-darwin-arm64?checksum=<checksum>", | ||
"darwin/amd64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-darwin-amd64?checksum=<checksum>, | ||
"linux/amd64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-linux-amd64?checksum=><checksum>" | ||
} | ||
} | ||
Expects a checksum in the form: | ||
<CHECKSUM> terpd-<VERSION>-<OS>-<ARCH>[.tar.gz] | ||
<CHECKSUM> terpd-<VERSION>-<OS>-<ARCH>[.tar.gz] | ||
... | ||
Example: | ||
f838618633c1d42f593dc33d26b25842f5900961e987fc08570bb81a062e311d terpd-4.2.0-linux-amd64 | ||
fa6699a763487fe6699c8720a2a9be4e26a4f45aafaec87aa0c3aced4cbdd155 terpd-4.2.0-linux-amd64.tar.gz | ||
(From: https://github.com/terpnetwork/terp-core/releases/download/v16.1.1/sha256sum.txt) | ||
❯ python create_binaries_json.py --tag v16.1.1 | ||
Output: | ||
{ | ||
"binaries": { | ||
"linux/arm64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-linux-arm64?checksum=<checksum>", | ||
"darwin/arm64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-darwin-arm64?checksum=<checksum>", | ||
"darwin/amd64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-darwin-amd64?checksum=<checksum>", | ||
"linux/amd64": "https://github.com/terpnetwork/terp-core/releases/download/16.1.1/terpd-4.2.0-linux-amd64?checksum=><checksum>" | ||
} | ||
} | ||
Expect a checksum to be present at: | ||
https://github.com/terpnetwork/terp-core/releases/download/<TAG>/sha256sum.txt | ||
""" | ||
|
||
import requests | ||
import json | ||
import argparse | ||
import re | ||
import sys | ||
|
||
def validate_tag(tag): | ||
pattern = '^v[0-9]+.[0-9]+.[0-9]+$' | ||
return bool(re.match(pattern, tag)) | ||
|
||
def download_checksums(checksums_url): | ||
|
||
response = requests.get(checksums_url) | ||
if response.status_code != 200: | ||
raise ValueError(f"Failed to fetch sha256sum.txt. Status code: {response.status_code}") | ||
return response.text | ||
|
||
def checksums_to_binaries_json(checksums): | ||
|
||
binaries = {} | ||
|
||
# Parse the content and create the binaries dictionary | ||
for line in checksums.splitlines(): | ||
checksum, filename = line.split(' ') | ||
|
||
# exclude tar.gz files | ||
if not filename.endswith('.tar.gz') and filename.startswith('terpd'): | ||
try: | ||
_, tag, platform, arch = filename.split('-') | ||
except ValueError: | ||
print(f"Error: Expected binary name in the form: terpd-X.Y.Z-platform-architecture, but got {filename}") | ||
sys.exit(1) | ||
_, tag, platform, arch, = filename.split('-') | ||
# exclude universal binaries and windows binaries | ||
if arch == 'all' or platform == 'windows': | ||
continue | ||
binaries[f"{platform}/{arch}"] = f"https://github.com/terpnetwork/terp-core/releases/download/v{tag}/{filename}?checksum=sha256:{checksum}" | ||
|
||
binaries_json = { | ||
"binaries": binaries | ||
} | ||
|
||
return json.dumps(binaries_json, indent=2) | ||
|
||
def main(): | ||
|
||
parser = argparse.ArgumentParser(description="Create binaries json") | ||
parser.add_argument('--tag', metavar='tag', type=str, help='the tag to use (e.g v16.1.1)') | ||
parser.add_argument('--checksums_url', metavar='checksums_url', type=str, help='URL to the checksum') | ||
|
||
args = parser.parse_args() | ||
|
||
# Validate the tag format | ||
if args.tag and not validate_tag(args.tag): | ||
print("Error: The provided tag does not follow the 'vX.Y.Z' format.") | ||
sys.exit(1) | ||
|
||
# Ensure that only one of --tag or --checksums_url is specified | ||
if not bool(args.tag) ^ bool(args.checksums_url): | ||
parser.error("Only one of tag or --checksums_url must be specified") | ||
sys.exit(1) | ||
|
||
checksums_url = args.checksums_url if args.checksums_url else f"https://github.com/terpnetwork/terp-core/releases/download/{args.tag}/sha256sum.txt" | ||
checksums = download_checksums(checksums_url) | ||
binaries_json = checksums_to_binaries_json(checksums) | ||
print(binaries_json) | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
certifi==2023.7.22 | ||
charset-normalizer==3.2.0 | ||
idna==3.4 | ||
requests==2.31.0 | ||
urllib3==2.0.7 |
116 changes: 116 additions & 0 deletions
116
scripts/release/create_upgrade_guide/UPGRADE_TEMPLATE.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# Mainnet Upgrade Guide: From Version $CURRENT_VERSION to $UPGRADE_VERSION | ||
|
||
## Overview | ||
|
||
- **$UPGRADE_VERSION Proposal**: [Proposal Page](https://www.ping.pub/terp/gov/$PROPOSAL_ID) | ||
- **$UPGRADE_VERSION Upgrade Block Height**: $UPGRADE_BLOCK | ||
- **$UPGRADE_VERSION Upgrade Countdown**: [Block Countdown](https://testnet.itrocket.net/terp/block/$UPGRADE_BLOCK) | ||
|
||
## Hardware Requirements | ||
|
||
### Memory Specifications | ||
|
||
Although this upgrade is not expected to be resource-intensive, a minimum of 64GB of RAM is advised. If you cannot meet this requirement, setting up a swap space is recommended. | ||
|
||
#### Configuring Swap Space | ||
|
||
*Execute these commands to set up a 32GB swap space*: | ||
|
||
```sh | ||
sudo swapoff -a | ||
sudo fallocate -l 32G /swapfile | ||
sudo chmod 600 /swapfile | ||
sudo mkswap /swapfile | ||
sudo swapon /swapfile | ||
``` | ||
|
||
*To ensure the swap space persists after reboot*: | ||
|
||
```sh | ||
sudo cp /etc/fstab /etc/fstab.bak | ||
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab | ||
``` | ||
|
||
For an in-depth guide on swap configuration, please refer to [this tutorial](https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-20-04). | ||
|
||
--- | ||
|
||
## Cosmovisor Configuration | ||
|
||
### Initial Setup (For First-Time Users) | ||
|
||
If you have not previously configured Cosmovisor, follow this section; otherwise, proceed to the next section. | ||
|
||
Cosmovisor is strongly recommended for validators to minimize downtime during upgrades. It automates the binary replacement process according to on-chain `SoftwareUpgrade` proposals. | ||
|
||
Documentation for Cosmovisor can be found [here](https://docs.cosmos.network/main/tooling/cosmovisor). | ||
|
||
#### Installation Steps | ||
|
||
*Run these commands to install and configure Cosmovisor*: | ||
|
||
```sh | ||
go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/[email protected] | ||
mkdir -p ~/.terp | ||
mkdir -p ~/.terp/cosmovisor | ||
mkdir -p ~/.terp/cosmovisor/genesis | ||
mkdir -p ~/.terp/cosmovisor/genesis/bin | ||
mkdir -p ~/.terp/cosmovisor/upgrades | ||
cp $GOPATH/bin/terpd ~/.terp/cosmovisor/genesis/bin | ||
mkdir -p ~/.terp/cosmovisor/upgrades/$CURRENT_VERSION/bin | ||
cp $GOPATH/bin/terpd ~/.terp/cosmovisor/upgrades/$CURRENT_VERSION/bin | ||
``` | ||
|
||
*Add these lines to your profile to set up environment variables*: | ||
|
||
```sh | ||
echo "# Cosmovisor Setup" >> ~/.profile | ||
echo "export DAEMON_NAME=terpd" >> ~/.profile | ||
echo "export DAEMON_HOME=$HOME/.terp" >> ~/.profile | ||
echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=false" >> ~/.profile | ||
echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.profile | ||
echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.profile | ||
echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.profile | ||
source ~/.profile | ||
``` | ||
|
||
### Upgrading to $UPGRADE_VERSION | ||
|
||
*To prepare for the upgrade, execute these commands*: | ||
|
||
```sh | ||
mkdir -p ~/.terp/cosmovisor/upgrades/$UPGRADE_VERSION/bin | ||
cd $HOME/terp-core | ||
git pull | ||
git checkout $UPGRADE_TAG | ||
make build | ||
cp build/terpd ~/.terp/cosmovisor/upgrades/$UPGRADE_VERSION/bin | ||
``` | ||
|
||
At the designated block height, Cosmovisor will automatically upgrade to version $UPGRADE_VERSION. | ||
|
||
--- | ||
|
||
## Manual Upgrade Procedure | ||
|
||
Follow these steps if you opt for a manual upgrade: | ||
|
||
1. Monitor Terp Network until it reaches the specified upgrade block height: $UPGRADE_BLOCK. | ||
2. Observe for a panic message followed by continuous peer logs, then halt the daemon. | ||
3. Perform these steps: | ||
|
||
```sh | ||
cd $HOME/terp-core | ||
git pull | ||
git checkout $UPGRADE_TAG | ||
make install | ||
``` | ||
|
||
4. Restart the Terp-Core daemon and observe the upgrade. | ||
|
||
--- | ||
|
||
## Additional Resources | ||
|
||
- Terp Network Documentation: [Website](https://docs.terp.network) | ||
- Community Support: [Discord](https://discord.gg/pAxjcFnAFH) |
82 changes: 82 additions & 0 deletions
82
scripts/release/create_upgrade_guide/create_upgrade_guide.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import argparse | ||
from string import Template | ||
import argparse | ||
import re | ||
import sys | ||
|
||
# USAGE: | ||
# | ||
# This script generates a Mainnet Upgrade Guide using a template. It replaces variables like current_version, upgrade_version, | ||
# proposal_id, and upgrade_block based on the arguments provided. | ||
# | ||
# Example: | ||
# Run the script using the following command: | ||
# python create_upgrade_guide.py --current_version=v18 --upgrade_version=v19 --proposal_id=606 --upgrade_block=11317300 --upgrade_tag=v19.0.0 | ||
# | ||
# Arguments: | ||
# --current_version : The current version before upgrade (e.g., v18) | ||
# --upgrade_version : The version to upgrade to (e.g., v19) | ||
# --proposal_id : The proposal ID related to the upgrade | ||
# --upgrade_block : The block height at which the upgrade will occur | ||
# --upgrade_tag : The specific version tag for the upgrade (e.g., v19.0.0) | ||
# | ||
# This will read a template file and replace the variables in it to generate a complete Mainnet Upgrade Guide. | ||
|
||
|
||
def validate_tag(tag): | ||
pattern = '^v[0-9]+.[0-9]+.[0-9]+$' | ||
return bool(re.match(pattern, tag)) | ||
|
||
|
||
def validate_version(version): | ||
# Regex to match 'v' followed by a number | ||
pattern = '^v\d+$' | ||
return bool(re.match(pattern, version)) | ||
|
||
|
||
def main(): | ||
|
||
parser = argparse.ArgumentParser(description="Create upgrade guide from template") | ||
parser.add_argument('--current_version', '-c', metavar='current_version', type=str, required=True, help='Current version (e.g v1)') | ||
parser.add_argument('--upgrade_version', '-u', metavar='upgrade_version', type=str, required=True, help='Upgrade version (e.g v2)') | ||
parser.add_argument('--upgrade_tag', '-t', metavar='upgrade_tag', type=str, required=True, help='Upgrade tag (e.g v2.0.0)') | ||
parser.add_argument('--proposal_id', '-p', metavar='proposal_id', type=str, required=True, help='Proposal ID') | ||
parser.add_argument('--upgrade_block', '-b', metavar='upgrade_block', type=str, required=True, help='Upgrade block height') | ||
|
||
args = parser.parse_args() | ||
|
||
if not validate_version(args.current_version): | ||
print("Error: The provided current_version does not follow the 'vX' format.") | ||
sys.exit(1) | ||
|
||
if not validate_version(args.upgrade_version): | ||
print("Error: The provided upgrade_version does not follow the 'vX' format.") | ||
sys.exit(1) | ||
|
||
if not validate_tag(args.upgrade_tag): | ||
print("Error: The provided tag does not follow the 'vX.Y.Z' format.") | ||
sys.exit(1) | ||
|
||
# Read the template from an external file | ||
with open('UPGRADE_TEMPLATE.md', 'r') as f: | ||
markdown_template = f.read() | ||
|
||
# Initialize the template | ||
t = Template(markdown_template) | ||
|
||
# Substitute the variables | ||
# Use Template.safe_substitute() over Template.substitute() | ||
# This method won't throw an error for missing placeholders, making it suitable for partial replacements. | ||
filled_markdown = t.safe_substitute( | ||
CURRENT_VERSION=args.current_version, | ||
UPGRADE_VERSION=args.upgrade_version, | ||
UPGRADE_TAG=args.upgrade_tag, | ||
PROPOSAL_ID=args.proposal_id, | ||
UPGRADE_BLOCK=args.upgrade_block | ||
) | ||
|
||
print(filled_markdown) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |