mirror of
https://github.com/tendermint/tendermint.git
synced 2026-05-21 22:51:30 +00:00
create versioned e2e docker image
This commit is contained in:
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Docker
|
||||
# Build & Push rebuilds the tendermint docker image on every push to master and creation of tags
|
||||
# and pushes the image to https://hub.docker.com/r/interchainio/simapp/tags
|
||||
# and pushes the image to https://hub.docker.com/r/tendermint/tendermint/tags
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
||||
55
.github/workflows/e2e-docker.yml
vendored
Normal file
55
.github/workflows/e2e-docker.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
name: E2E Docker
|
||||
# builds and pushes tendermint e2e-node docker image on every creation of a tag
|
||||
# and pushes the image to https://hub.docker.com/r/tendermint/e2e-node/tags
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
DOCKER_IMAGE=tendermint/e2e-node
|
||||
VERSION=noop
|
||||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
elif [[ $GITHUB_REF == refs/heads/* ]]; then
|
||||
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
|
||||
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then
|
||||
VERSION=latest
|
||||
fi
|
||||
fi
|
||||
TAGS="${DOCKER_IMAGE}:${VERSION}"
|
||||
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
TAGS="$TAGS,${DOCKER_IMAGE}:${VERSION}"
|
||||
fi
|
||||
echo ::set-output name=tags::${TAGS}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@master
|
||||
with:
|
||||
platforms: all
|
||||
|
||||
- name: Set up Docker Build
|
||||
uses: docker/setup-buildx-action@v2.0.0
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/login-action@v2.0.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Publish to Docker Hub
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
with:
|
||||
context: .
|
||||
file: ./test/e2e/docker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.prep.outputs.tags }}
|
||||
@@ -1,7 +1,13 @@
|
||||
all: docker generator runner tests
|
||||
|
||||
docker:
|
||||
docker build --tag tendermint/e2e-node -f docker/Dockerfile ../..
|
||||
ifneq (,$(VERSION))
|
||||
git worktree add e2e-node $(VERSION)
|
||||
docker build --tag tendermint/e2e-node:$(VERSION) -f docker/Dockerfile ../..
|
||||
git worktree remove e2e-node
|
||||
else
|
||||
docker build --tag tendermint/e2e-node:$(shell git symbolic-ref -q --short HEAD) -f docker/Dockerfile ../..
|
||||
endif
|
||||
|
||||
node:
|
||||
go build -o build/node -tags badgerdb,boltdb,cleveldb,rocksdb ./node
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# This testnet is run by CI, and attempts to cover a broad range of
|
||||
# functionality with a single network.
|
||||
|
||||
version = "master"
|
||||
evidence = 5
|
||||
initial_height = 1000
|
||||
initial_state = {initial01 = "a", initial02 = "b", initial03 = "c"}
|
||||
|
||||
@@ -10,6 +10,9 @@ import (
|
||||
|
||||
// Manifest represents a TOML testnet manifest.
|
||||
type Manifest struct {
|
||||
// Version of the tendermint e2e-node to use
|
||||
Version string `toml:"version"`
|
||||
|
||||
// IPv6 uses IPv6 networking instead of IPv4. Defaults to IPv4.
|
||||
IPv6 bool `toml:"ipv6"`
|
||||
|
||||
|
||||
@@ -8,11 +8,14 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
@@ -25,8 +28,11 @@ const (
|
||||
proxyPortFirst uint32 = 5701
|
||||
networkIPv4 = "10.186.73.0/24"
|
||||
networkIPv6 = "fd80:b10c::/48"
|
||||
defaultVersion = "master"
|
||||
)
|
||||
|
||||
var IsVersionValid = regexp.MustCompile(`master|v0.3[4-6]+.([0-9]+|x)`)
|
||||
|
||||
type Mode string
|
||||
type Protocol string
|
||||
type Perturbation string
|
||||
@@ -61,6 +67,7 @@ type Testnet struct {
|
||||
Name string
|
||||
File string
|
||||
Dir string
|
||||
Version string
|
||||
IP *net.IPNet
|
||||
InitialHeight int64
|
||||
InitialState map[string]string
|
||||
@@ -155,6 +162,9 @@ func LoadTestnet(file string) (*Testnet, error) {
|
||||
if testnet.ABCIProtocol == "" {
|
||||
testnet.ABCIProtocol = string(ProtocolBuiltin)
|
||||
}
|
||||
if testnet.Version == "" {
|
||||
testnet.Version = defaultVersion
|
||||
}
|
||||
|
||||
// Set up nodes, in alphabetical order (IPs and ports get same order).
|
||||
nodeNames := []string{}
|
||||
@@ -300,6 +310,9 @@ func (t Testnet) Validate() error {
|
||||
if len(t.Nodes) == 0 {
|
||||
return errors.New("network has no nodes")
|
||||
}
|
||||
if !IsVersionValid.MatchString(t.Version) {
|
||||
return fmt.Errorf("invalid network version %s", t.Version)
|
||||
}
|
||||
switch t.KeyType {
|
||||
case "", types.ABCIPubKeyTypeEd25519, types.ABCIPubKeyTypeSecp256k1:
|
||||
default:
|
||||
@@ -472,6 +485,15 @@ func (n Node) Stateless() bool {
|
||||
return n.Mode == ModeLight || n.Mode == ModeSeed
|
||||
}
|
||||
|
||||
func (n Node) DB(name string) (dbm.DB, error) {
|
||||
dbType := dbm.BackendType(n.Database)
|
||||
return dbm.NewDB(name, dbType, filepath.Join(n.Dir(), "data"))
|
||||
}
|
||||
|
||||
func (n Node) Dir() string {
|
||||
return filepath.Join(n.Testnet.Dir, n.Name)
|
||||
}
|
||||
|
||||
// keyGenerator generates pseudorandom Ed25519 keys based on a seed.
|
||||
type keyGenerator struct {
|
||||
random *rand.Rand
|
||||
|
||||
@@ -353,6 +353,14 @@ Does not run any perbutations.
|
||||
},
|
||||
})
|
||||
|
||||
cli.root.AddCommand(&cobra.Command{
|
||||
Use: "upgrade",
|
||||
Short: "Runs a testnet through an upgrade process from the specified version to the current version",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return Upgrade(cmd.Context(), cli.testnet, logger)
|
||||
},
|
||||
})
|
||||
|
||||
return cli
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ services:
|
||||
labels:
|
||||
e2e: true
|
||||
container_name: {{ .Name }}
|
||||
image: tendermint/e2e-node
|
||||
image: tendermint/e2e-node:{{ $.Version }}
|
||||
{{- if eq .ABCIProtocol "builtin" }}
|
||||
entrypoint: /usr/bin/entrypoint-builtin
|
||||
{{- else if .LogLevel }}
|
||||
|
||||
94
test/e2e/runner/upgrade.go
Normal file
94
test/e2e/runner/upgrade.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
|
||||
|
||||
"github.com/tendermint/tendermint/scripts/keymigrate"
|
||||
"github.com/tendermint/tendermint/scripts/scmigrate"
|
||||
)
|
||||
|
||||
func Upgrade(ctx context.Context, testnet *e2e.Testnet, logger log.Logger) error {
|
||||
if err := Cleanup(logger, testnet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := Setup(logger, testnet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := rand.New(rand.NewSource(randomSeed)) // nolint: gosec
|
||||
|
||||
chLoadResult := make(chan error)
|
||||
|
||||
lctx, loadCancel := context.WithCancel(ctx)
|
||||
defer loadCancel()
|
||||
go func() {
|
||||
chLoadResult <- Load(lctx, logger, r, testnet)
|
||||
}()
|
||||
|
||||
if err := Start(ctx, logger, testnet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := Wait(ctx, logger, testnet, 10); err != nil { // allow some txs to go through
|
||||
return err
|
||||
}
|
||||
|
||||
loadCancel()
|
||||
if err := <-chLoadResult; err != nil {
|
||||
return fmt.Errorf("transaction load failed: %w", err)
|
||||
}
|
||||
|
||||
// stop the network
|
||||
if err := execCompose(testnet.Dir, "down"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := Migrate(ctx, logger, testnet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := Start(ctx, logger, testnet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Migrate(ctx context.Context, logger log.Logger, testnet *e2e.Testnet) error {
|
||||
stores := []string{
|
||||
"tx_index",
|
||||
"light",
|
||||
"blockstore",
|
||||
"state",
|
||||
"evidence",
|
||||
}
|
||||
for _, node := range testnet.Nodes {
|
||||
if strings.HasPrefix(oldVersion, "v0.34") && newVersion > "v0.35" {
|
||||
for _, store := range stores {
|
||||
db, err := node.DB(store)
|
||||
if err != nil {
|
||||
return fmt.Errorf("migrating db: %w", err)
|
||||
}
|
||||
|
||||
if err = keymigrate.Migrate(ctx, db); err != nil {
|
||||
return fmt.Errorf("running migration for context %q: %w",
|
||||
store, err)
|
||||
}
|
||||
|
||||
if store == "blockstore" {
|
||||
if err := scmigrate.Migrate(ctx, db); err != nil {
|
||||
return fmt.Errorf("running seen commit migration: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user