From e5a00fdca921642bf607b5c681e5e5ff52f8fa6d Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Mon, 6 May 2019 13:33:19 -0400 Subject: [PATCH] Add GCP test configuration and p2p-host-ip flag (#2510) * Add GCP startup script * add flag for external IP * specify that it must be for linux * /deploy/create * gofmt --- beacon-chain/main.go | 1 + beacon-chain/node/p2p_config.go | 1 + scripts/gcp_startup_script.sh | 74 +++++++++++++++++++++++++++++++++ shared/cmd/flags.go | 6 +++ shared/p2p/service.go | 12 ++++++ 5 files changed, 94 insertions(+) create mode 100644 scripts/gcp_startup_script.sh diff --git a/beacon-chain/main.go b/beacon-chain/main.go index 3e7292867e1c..27cf0f2506e4 100644 --- a/beacon-chain/main.go +++ b/beacon-chain/main.go @@ -56,6 +56,7 @@ func main() { cmd.BootstrapNode, cmd.RelayNode, cmd.P2PPort, + cmd.P2PHost, cmd.DataDirFlag, cmd.VerbosityFlag, cmd.EnableTracingFlag, diff --git a/beacon-chain/node/p2p_config.go b/beacon-chain/node/p2p_config.go index e1250684c446..2aec13f2e2a2 100644 --- a/beacon-chain/node/p2p_config.go +++ b/beacon-chain/node/p2p_config.go @@ -41,6 +41,7 @@ func configureP2P(ctx *cli.Context) (*p2p.Server, error) { NoDiscovery: ctx.GlobalBool(cmd.NoDiscovery.Name), BootstrapNodeAddr: ctx.GlobalString(cmd.BootstrapNode.Name), RelayNodeAddr: ctx.GlobalString(cmd.RelayNode.Name), + HostAddress: ctx.GlobalString(cmd.P2PHost.Name), Port: ctx.GlobalInt(cmd.P2PPort.Name), DepositContractAddress: contractAddress, }) diff --git a/scripts/gcp_startup_script.sh b/scripts/gcp_startup_script.sh new file mode 100644 index 000000000000..cf15366ab1eb --- /dev/null +++ b/scripts/gcp_startup_script.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +: ' +# *** Instructions *** + +# Build beacon chain for linux +bazel build --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 //beacon-chain + +# Tar the binary +tar czvf /tmp/beacon-chain.tar.gz --directory=bazel-bin/beacon-chain/linux_amd64_stripped beacon-chain + +# Copy to cloud storage +gsutil cp /tmp/beacon-chain.tar.gz gs://prysmaticlabs/beacon-chain-deployment.tar.gz + +# Create template instance +gcloud compute instance-templates create beacon-chain \ + --project=prysmaticlabs \ + --image-family=debian-9 \ + --image-project=debian-cloud \ + --machine-type=g1-small \ + --preemptible \ + --scopes userinfo-email,cloud-platform \ + --metadata app-location=gs://prysmaticlabs/beacon-chain-deployment.tar.gz \ + --metadata-from-file startup-script=scripts/gcp_startup_script.sh \ + --tags beacon-chain + +# Navigate to https://console.cloud.google.com/compute/instanceTemplates/list?project=prysmaticlabs +# and create a new instance group with the template. +' + + + +set -ex + +# Talk to the metadata server to get the project id and location of application binary. +PROJECTID=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google") +DEPLOY_LOCATION=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/app-location" -H "Metadata-Flavor: Google") +EXTERNAL_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google") + +# Install logging monitor. The monitor will automatically pickup logs send to +# syslog. +curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash +service google-fluentd restart & + +# Install dependencies from apt +apt-get update +apt-get install -yq ca-certificates supervisor + +# Get the application tar from the GCS bucket. +gsutil cp $DEPLOY_LOCATION /app.tar +mkdir -p /app +tar xvzf /app.tar -C /app +chmod +x /app/beacon-chain + +# Create a goapp user. The application will run as this user. +getent passwd goapp || useradd -m -d /home/goapp goapp +chown -R goapp:goapp /app + +# Configure supervisor to run the Go app. +cat >/etc/supervisor/conf.d/goapp.conf << EOF +[program:goapp] +directory=/app +command=/app/beacon-chain --p2p-host-ip=${EXTERNAL_IP} --clear-db +autostart=true +autorestart=true +user=goapp +environment=HOME="/home/goapp",USER="goapp" +stdout_logfile=syslog +stderr_logfile=syslog +EOF + +supervisorctl reread +supervisorctl update + +# Application should now be running under supervisor diff --git a/shared/cmd/flags.go b/shared/cmd/flags.go index 56e7837c33b9..b7da2ab41792 100644 --- a/shared/cmd/flags.go +++ b/shared/cmd/flags.go @@ -72,6 +72,12 @@ var ( Usage: "The port used by libp2p.", Value: 12000, } + // P2PHost defines the host IP to be used by libp2p. + P2PHost = cli.StringFlag{ + Name: "p2p-host-ip", + Usage: "The IP address advertised by libp2p. This may be used to advertise an external IP.", + Value: "", + } // ClearDB tells the beacon node to remove any previously stored data at the data directory. ClearDB = cli.BoolFlag{ Name: "clear-db", diff --git a/shared/p2p/service.go b/shared/p2p/service.go index dff715e9ae13..b28aa8866144 100644 --- a/shared/p2p/service.go +++ b/shared/p2p/service.go @@ -22,6 +22,7 @@ import ( protocol "github.com/libp2p/go-libp2p-protocol" pubsub "github.com/libp2p/go-libp2p-pubsub" rhost "github.com/libp2p/go-libp2p/p2p/host/routed" + "github.com/multiformats/go-multiaddr" pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" "github.com/prysmaticlabs/prysm/shared/event" "github.com/prysmaticlabs/prysm/shared/featureconfig" @@ -63,6 +64,7 @@ type ServerConfig struct { NoDiscovery bool BootstrapNodeAddr string RelayNodeAddr string + HostAddress string Port int DepositContractAddress string } @@ -73,6 +75,16 @@ func NewServer(cfg *ServerConfig) (*Server, error) { opts := buildOptions(cfg.Port) if cfg.RelayNodeAddr != "" { opts = append(opts, libp2p.AddrsFactory(withRelayAddrs(cfg.RelayNodeAddr))) + } else if cfg.HostAddress != "" { + opts = append(opts, libp2p.AddrsFactory(func(addrs []multiaddr.Multiaddr) []multiaddr.Multiaddr { + external, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", cfg.HostAddress, cfg.Port)) + if err != nil { + log.WithError(err).Error("Unable to create external multiaddress") + } else { + addrs = append(addrs, external) + } + return addrs + })) } if !checkAvailablePort(cfg.Port) { cancel()