Skip to content

Commit

Permalink
ci: Dockerfile & Docker Pipeline & Docker Compose Improvements (#1821)
Browse files Browse the repository at this point in the history
* update

* updates

* update

* docker improvements

* docker improvements

* docker improvements

* docker improvements

* docker improvements

* updated binary download script

* updated binary download script

* remove the patch that is no longer needed

* remove tmux

* fix typo

* update the way github actions docker pipeline pulls in release title

* fixed localnet docker image

* removing unused file

* updating the e2e test with docekr compose to use the localnet dockerfile

* fixing the e2e test reference

---------

Co-authored-by: Lucas Bertrand <[email protected]>
  • Loading branch information
gzukel and lumtis authored Mar 4, 2024
1 parent fcbb639 commit 01526a5
Show file tree
Hide file tree
Showing 21 changed files with 786 additions and 1,456 deletions.
33 changes: 23 additions & 10 deletions .github/workflows/docker-build-and-push.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
name: Zetacored-Docker-Build

on:
pull_request:
release:
types:
- closed
branches:
- 'main'
- created
workflow_dispatch:
inputs:
version:
Expand All @@ -32,9 +30,14 @@ jobs:
fetch-depth: 0

- name: Set Version from the PR title.
if: github.event_name == 'pull_request'
if: github.event_name != 'workflow_dispatch'
run: |
echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.pull_request.title }}" >> ${GITHUB_ENV}
LATEST_RELEASE=$(curl -s -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
https://api.github.com/repos/${{ github.repository }}/releases/latest)
RELEASE_TITLE=$(echo $LATEST_RELEASE | jq -r .name)
echo "Latest release title: $RELEASE_TITLE"
echo "GITHUB_TAG_MAJOR_VERSION=$RELEASE_TITLE" >> $GITHUB_ENV
- name: Set Version for Hotfix Release from Input.
if: github.event_name != 'pull_request'
Expand Down Expand Up @@ -64,9 +67,14 @@ jobs:
fetch-depth: 0

- name: Set Version from the PR title.
if: github.event_name == 'pull_request'
if: github.event_name != 'workflow_dispatch'
run: |
echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.pull_request.title }}" >> ${GITHUB_ENV}
LATEST_RELEASE=$(curl -s -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
https://api.github.com/repos/${{ github.repository }}/releases/latest)
RELEASE_TITLE=$(echo $LATEST_RELEASE | jq -r .name)
echo "Latest release title: $RELEASE_TITLE"
echo "GITHUB_TAG_MAJOR_VERSION=$RELEASE_TITLE" >> $GITHUB_ENV
- name: Set Version for Hotfix Release from Input.
if: github.event_name != 'pull_request'
Expand Down Expand Up @@ -107,9 +115,14 @@ jobs:
fetch-depth: 0

- name: Set Version from the PR title.
if: github.event_name == 'pull_request'
if: github.event_name != 'workflow_dispatch'
run: |
echo "GITHUB_TAG_MAJOR_VERSION=${{ github.event.pull_request.title }}" >> ${GITHUB_ENV}
LATEST_RELEASE=$(curl -s -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
https://api.github.com/repos/${{ github.repository }}/releases/latest)
RELEASE_TITLE=$(echo $LATEST_RELEASE | jq -r .name)
echo "Latest release title: $RELEASE_TITLE"
echo "GITHUB_TAG_MAJOR_VERSION=$RELEASE_TITLE" >> $GITHUB_ENV
- name: Set Version for Hotfix Release from Input.
if: github.event_name != 'pull_request'
Expand Down
66 changes: 34 additions & 32 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,51 +1,53 @@
# Purpose: This Dockerfile creates an environment for running ZetaChain
# It contains:
# - zetacored: the ZetaChain node binary
# - zetaclientd: the ZetaChain client binary for observers
# - zetae2e: the ZetaChain end-to-end tests CLI

FROM golang:1.20-alpine3.18
# Build Stage
FROM golang:1.20-alpine3.18 AS builder

ENV GOPATH /go
ENV GOOS=linux
ENV CGO_ENABLED=1

RUN apk --no-cache add git make build-base jq openssh libusb-dev linux-headers bash curl tmux
RUN ssh-keygen -b 2048 -t rsa -f /root/.ssh/localtest.pem -q -N ""
# Install build dependencies
RUN apk --no-cache add git make build-base jq openssh libusb-dev linux-headers bash curl python3 py3-pip

# Set the working directory
WORKDIR /go/delivery/zeta-node

# Copy module files and download dependencies
COPY go.mod .
COPY go.sum .

RUN go mod download

# Copy the rest of the source code and build the application
COPY . .
RUN make install
RUN make install-zetae2e
#
#FROM golang:1.20-alpine

#RUN apk --no-cache add openssh jq tmux vim curl bash
RUN ssh-keygen -A
WORKDIR /root
RUN make install

RUN cp /root/.ssh/localtest.pem.pub /root/.ssh/authorized_keys
# Run Stage
FROM alpine:3.18

RUN cp /go/bin/zetaclientd /usr/local/bin
RUN cp /go/bin/zetacored /usr/local/bin
RUN cp /go/bin/zetae2e /usr/local/bin
# Copy Start Script Helpers
COPY contrib/docker-scripts/* /scripts/

COPY contrib/localnet/scripts /root
COPY contrib/localnet/preparams /root/preparams
COPY contrib/localnet/ssh_config /root/.ssh/config
COPY contrib/localnet/zetacored /root/zetacored
COPY contrib/localnet/tss /root/tss
# Install runtime dependencies
RUN apk --no-cache add git jq bash curl python3 libusb-dev linux-headers make build-base wget py3-pip qemu-img qemu-system-x86_64 && \
pip install requests && \
chmod a+x -R /scripts && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-2.31-r0.apk && \
apk add --force-overwrite --allow-untrusted glibc-2.31-r0.apk

RUN chmod 755 /root/*.sh
RUN chmod 700 /root/.ssh
RUN chmod 600 /root/.ssh/*
# Copy the binaries from the build stage
COPY --from=builder /go/bin/zetaclientd /usr/local/bin/zetaclientd
COPY --from=builder /go/bin/zetacored /usr/local/bin/zetacored

# Set the working directory
WORKDIR /usr/local/bin
ENV SHELL /bin/sh
EXPOSE 22

ENTRYPOINT ["/usr/sbin/sshd", "-D"]
# Set the default shell
ENV SHELL /bin/bash

EXPOSE 26656
EXPOSE 1317
EXPOSE 8545
EXPOSE 8546
EXPOSE 9090
EXPOSE 26657
EXPOSE 9091
52 changes: 52 additions & 0 deletions Dockerfile-localnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
FROM golang:1.20-alpine3.18

ENV GOPATH /go
ENV GOOS=linux
ENV CGO_ENABLED=1

RUN apk --no-cache add git make build-base jq openssh libusb-dev linux-headers bash curl tmux python3 py3-pip
RUN pip install requests
RUN ssh-keygen -b 2048 -t rsa -f /root/.ssh/localtest.pem -q -N ""

WORKDIR /go/delivery/zeta-node
COPY go.mod .
COPY go.sum .
#RUN --mount=type=cache,target=/root/.cache/go-build \
# go mod download
RUN go mod download
COPY . .

#RUN --mount=type=cache,target=/root/.cache/go-build \
# make install
#RUN --mount=type=cache,target=/root/.cache/go-build \
# make install-zetae2e
RUN make install
RUN make install-zetae2e
#
#FROM golang:1.20-alpine

#RUN apk --no-cache add openssh jq tmux vim curl bash
RUN ssh-keygen -A
WORKDIR /root

RUN cp /root/.ssh/localtest.pem.pub /root/.ssh/authorized_keys

RUN cp /go/bin/zetaclientd /usr/local/bin
RUN cp /go/bin/zetacored /usr/local/bin
RUN cp /go/bin/zetae2e /usr/local/bin

COPY contrib/localnet/scripts /root
COPY contrib/localnet/preparams /root/preparams
COPY contrib/localnet/ssh_config /root/.ssh/config
COPY contrib/localnet/zetacored /root/zetacored
COPY contrib/localnet/tss /root/tss

RUN chmod 755 /root/*.sh
RUN chmod 700 /root/.ssh
RUN chmod 600 /root/.ssh/*

WORKDIR /usr/local/bin
ENV SHELL /bin/sh
EXPOSE 22

ENTRYPOINT ["/usr/sbin/sshd", "-D"]
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ generate: proto openapi specs typescript docs-zetacored

zetanode:
@echo "Building zetanode"
$(DOCKER) build -t zetanode -f ./Dockerfile .
$(DOCKER) build -t zetanode -f ./Dockerfile-localnet .
$(DOCKER) build -t orchestrator -f contrib/localnet/orchestrator/Dockerfile.fastbuild .
.PHONY: zetanode

Expand Down Expand Up @@ -266,7 +266,10 @@ release:
###############################################################################

mainnet-zetarpc-node:
cd contrib/local-mainnet/zetacored && docker-compose up
cd contrib/mainnet/zetacored && DOCKER_TAG=$(DOCKER_TAG) docker-compose up

mainnet-bitcoind-node:
cd contrib/local-mainnet/bitcoind && docker-compose up
cd contrib/mainnet/bitcoind && DOCKER_TAG=$(DOCKER_TAG) docker-compose up

athens3-zetarpc-node:
cd contrib/athens3/zetacored && DOCKER_TAG=$(DOCKER_TAG) docker-compose up
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,17 @@
* Added docker-compose and make commands for launching full nodes. `make mainnet-zetarpc-node` `make mainnet-bitcoind-node`
* Made adjustments to the docker-compose for launching mainnet full nodes to include examples of using the docker images build from the docker image build pipeline.
* [1736](https://github.com/zeta-chain/node/pull/1736) - chore: add Ethermint endpoints to OpenAPI
* Re-wrote Dockerfile for building Zetacored docker images.
* Adjusted the docker-compose files for Zetacored nodes to utilize the new docker image.
* Added scripts for the new docker image that facilitate the start up automation.
* Adjusted the docker pipeline slightly to pull the version on PR from the app.go file.
* [1781](https://github.com/zeta-chain/node/pull/1781) - add codecov coverage report in CI

### Features

* [1425](https://github.com/zeta-chain/node/pull/1425) add `whitelist-erc20` command


### Chores

* [1729](https://github.com/zeta-chain/node/pull/1729) - add issue templates
Expand Down
44 changes: 44 additions & 0 deletions contrib/athens3/zetacored/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
version: '3.8'
services:
zetachain_mainnet_rpc:
platform: linux/amd64
#This will build the binary from the GIT_REF you are locally on.
# build:
# context: ../../..
# dockerfile: Dockerfile
image: zetachain/zetacored:${DOCKER_TAG:-ubuntu-v14}
environment:
DAEMON_HOME: "/root/.zetacored"
NETWORK: athens3
#RESTORE_TYPE=snapshot/snapshot-archive/statesync
RESTORE_TYPE: "statesync"
SNAPSHOT_API: https://snapshots.zetachain.com
TRUST_HEIGHT_DIFFERENCE_STATE_SYNC: 40000
COSMOVISOR_VERSION: "v1.5.0"
CHAIN_ID: "athens_7001-1"
COSMOVISOR_CHECKSUM: "626dfc58c266b85f84a7ed8e2fe0e2346c15be98cfb9f9b88576ba899ed78cdc"
VISOR_NAME: "cosmovisor"
DAEMON_NAME: "zetacored"
DAEMON_ALLOW_DOWNLOAD_BINARIES: "false"
DAEMON_RESTART_AFTER_UPGRADE: "true"
UNSAFE_SKIP_BACKUP: "true"
CLIENT_DAEMON_NAME: "zetaclientd"
CLIENT_DAEMON_ARGS: ""
CLIENT_SKIP_UPGRADE: "true"
CLIENT_START_PROCESS: "false"
MONIKER: local-test
RE_DO_START_SEQUENCE: "false"
ports:
- "26656:26656"
- "1317:1317"
- "8545:8545"
- "8546:8546"
- "26657:26657"
- "9090:9090"
- "9091:9091"
volumes:
- zetacored_data:/root/.zetacored/
entrypoint: bash /scripts/start.sh

volumes:
zetacored_data:
98 changes: 98 additions & 0 deletions contrib/docker-scripts/download_binaries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import re
import requests
import os
import json
import logging
import sys
import shutil


# Logger class for easier logging setup
class Logger:
def __init__(self):
self.log = logging.getLogger()
self.log.setLevel(logging.INFO)
self.handler = logging.StreamHandler(sys.stdout)
self.handler.setLevel(logging.DEBUG)
self.formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
self.handler.setFormatter(self.formatter)
self.log.addHandler(self.handler)


# Initialize logger instance
logger = Logger()

# Define the path where upgrades will be stored, using an environment variable for the base path
upgrade_path = f'{os.environ["DAEMON_HOME"]}/cosmovisor/upgrades/'


# Function to find the latest patch version of a binary based on major and optional minor version
def find_latest_patch_version(major_version, minor_version=None):
# Define a regex pattern to match version directories
pattern = re.compile(
f"v{major_version}\.{minor_version}\.(\d+)" if minor_version else f"v{major_version}\.0\.(\d+)")
# List directories that match the version pattern
versions = [folder for folder in os.listdir(upgrade_path) if pattern.match(folder)]
if versions:
try:
# Find the maximum version, assuming it's the latest patch
latest_patch_version = max(versions)
# Return the path to the binary of the latest patch version
return os.path.join(upgrade_path, latest_patch_version, "bin", "zetacored")
except ValueError as e:
logger.log.error(f"Error finding latest patch version: {e}")
return None
return None


# Function to replace an old binary with a new one
def replace_binary(source, target):
try:
# Log deletion of old binary
if os.path.exists(target):
logger.log.info(f"Deleted old binary: {target}")
os.remove(target)
# Copy the new binary to the target location
shutil.copy(source, target)
logger.log.info(f"Binary replaced: {target} -> {source}")
except Exception as e:
logger.log.error(f"Error replacing binary: {e}")


# Parse JSON from an environment variable to get binary download information
info = json.loads(os.environ["DOWNLOAD_BINARIES"])

try:
# Iterate over binaries to download
for binary in info["binaries"]:
download_link = binary["download_url"]
binary_location = binary["binary_location"]
binary_directory = os.path.dirname(binary_location)
# Log download link
logger.log.info(f"DOWNLOAD LINK: {download_link}")
split_download_link = download_link.split("/")
# Log split download link parts
logger.log.info(f"SPLIT DOWNLOAD LINK: {split_download_link}")
# Extract binary name and version from the download link
binary_name = download_link.split("/")[8]
# Check if binary already exists
logger.log.info(f"CHECKING / DOWNLOADING {binary_location}")

if os.path.exists(binary_location):
# If binary exists, log and do nothing
logger.log.info(f"BINARY EXISTS ALREADY: {binary_location}")
else:
# If binary doesn't exist, download and save it
logger.log.info("BINARY DOES NOT EXIST.")
os.makedirs(binary_directory, exist_ok=True)
response = requests.get(download_link)
if response.status_code == 200:
with open(binary_location, "wb") as f:
f.write(response.content)
os.chmod(binary_location, 0o755)
logger.log.info("BINARY DOWNLOADED SUCCESSFULLY.")
else:
logger.log.info("FAILED TO DOWNLOAD BINARY. Status code:", response.status_code)
logger.log.info("BINARIES DOWNLOAD FINISHED...")
except Exception as e:
logger.log.error(str(e))
Loading

0 comments on commit 01526a5

Please sign in to comment.