Skip to content

Commit

Permalink
remote
Browse files Browse the repository at this point in the history
  • Loading branch information
Eduard-Voiculescu committed Jun 6, 2024
1 parent 5d94684 commit f5da2d3
Show file tree
Hide file tree
Showing 30 changed files with 1,433 additions and 49 deletions.
64 changes: 64 additions & 0 deletions .github/workflows/docker.remotebuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Build remote build docker image

on:
push:
branches:
- "feature/*"
workflow_dispatch:

env:
REGISTRY: ${{ secrets.REGISTRY }}
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push-image:
runs-on: ubuntu-20.04
if: "${{ !startsWith(github.event.head_commit.message, 'GitBook: [#') }}"
permissions:
contents: read
id-token: write
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v3

- id: "auth"
name: "Authenticate to Google Cloud"
uses: "google-github-actions/auth@v1"
with:
token_format: "access_token"
workload_identity_provider: ${{ secrets.GCR_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GCR_SERVICE_ACCOUNT }}

- name: Login to GCR
uses: docker/login-action@v1
with:
registry: gcr.io
username: oauth2accesstoken
password: ${{ steps.auth.outputs.access_token }}

- name: Generate docker tags/labels from github build context
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-remotebuild
tags: |
type=ref,event=tag
type=sha,prefix=
type=raw,enable=${{ github.ref == 'refs/heads/develop' }},value=develop
type=raw,enable=${{ startsWith(github.ref, 'refs/heads/release/v') }},value=${{ steps.extract_branch.outputs.release_train }}
flavor: |
latest=${{ startsWith(github.ref, 'refs/tags/') }}
- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
secrets: |
"github_token=${{ secrets.GHUB_ACCESS_TOKEN }}"
context: .
file: ./Dockerfile.remotebuild
push: true
tags: ${{ steps.meta.outputs.tags }}
# org.opencontainers.image.version will match the tag name
labels: ${{ steps.meta.outputs.labels }}
55 changes: 55 additions & 0 deletions Dockerfile.remotebuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
FROM rust:1.78-alpine as rust-builder

FROM golang:1.22-alpine3.19

ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo \
PATH=/usr/local/cargo/bin:$PATH \
RUST_VERSION=1.78.0

COPY --from=rust-builder /usr/local/cargo /usr/local/cargo/
COPY --from=rust-builder /usr/local/rustup /usr/local/rustup/

# Install needed rustup components
RUN rustup component add rustfmt && cargo install rustfmt || true
RUN rustup default stable
RUN rustup target add wasm32-unknown-unknown

# Install build essentials and curl
RUN apk update && apk add curl build-base sccache

# Set the Shared Compilation Cache for Cargo to use sccache
# This greatly improves build times when running concurrent builds
ENV RUSTC_WRAPPER=/usr/bin/sccache

# Install buf
RUN GO111MODULE=on GOBIN=/usr/local/bin go install github.com/bufbuild/buf/cmd/[email protected]

# Build substreams cli
# RUN curl -s https://api.github.com/repos/streamingfast/substreams/releases/latest | awk "/download.url.*linux_$(uname -m)/ {print \$2}" | sed 's/"//g' | curl -L $1 | tar zxf -

WORKDIR /app/data

# Add the entire cli source code
COPY . ./substreams-cli

WORKDIR /app/data/substreams-cli

# Install the substreams cli
RUN go install ./cmd/substreams

WORKDIR /app/data

# Remove all the source code to have a smaller image
RUN rm -r substreams-cli

# Add only the remotebuild source code
COPY remotebuild remotebuild

EXPOSE 9000

WORKDIR /app/data/remotebuild

RUN go install .

ENTRYPOINT [ "remotebuild" ]
138 changes: 138 additions & 0 deletions cmd/substreams/remote-build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package main

import (
"context"
"fmt"
"os"
"strings"

"github.com/spf13/cobra"
"github.com/streamingfast/cli"
"github.com/streamingfast/cli/sflags"
"github.com/streamingfast/dgrpc"
"go.uber.org/zap"

pbbuild "github.com/streamingfast/substreams/remotebuild/pb/sf/remotebuild/v1"
)

func init() {
remoteBuildCmd.Flags().StringArray("env", nil, "Environment variables to pass to the build server")
remoteBuildCmd.Flags().StringP("output-name", "o", "substreams.spkg", "Spkg name to collect")

rootCmd.AddCommand(remoteBuildCmd)
}

var remoteBuildCmd = &cobra.Command{
Use: "remote-build <remote-build-url> <zipped_source_code>",
Short: "Send request to remote build server to build and package a substreams",
Long: cli.Dedent(`
Call the remote build server to build and package a substream. You can also add in environment variables to pass to the build server.
Which will be injected in your substreams build. Make sure you align the make package output command with the collect pattern. By default
it will collect the substreams.spkg file, but if you gave it a different name with the -o or --output-file flag, you should pass it here too.
Example of valide make package commands: substreams pack:
.PHONE: package
pack: build
substreams pack -o my-substreams.spkg substreams.yaml
Then you will need to pass in the --output-name="my-substreams.spkg" flag to the remote-build command.
Examples: substreams remote-build localhost:9000 my-substream.zip --env="ENV0=test0,ENV1=test1" --env "ENV2=test2" --env "ENV3=test3" --output-name="my-substream.spkg"
`),
RunE: remoteBuildE,
Args: cobra.ExactArgs(2),
SilenceUsage: true,
}

func remoteBuildE(cmd *cobra.Command, args []string) error {
cloudRunServiceURL := args[0]
filepath := args[1]
envs := sflags.MustGetStringArray(cmd, "env")
spkgName := sflags.MustGetString(cmd, "output-name")

plaintext := false
if strings.HasPrefix(cloudRunServiceURL, "localhost") {
plaintext = true
}

cloudRunServiceURL = strings.Replace(cloudRunServiceURL, "https://", "", 1)
if len(strings.Split(cloudRunServiceURL, ":")) == 1 {
if plaintext {
cloudRunServiceURL = fmt.Sprintf("%s:9000", cloudRunServiceURL)
} else {
// add the port if it is missing
cloudRunServiceURL = fmt.Sprintf("%s:443", cloudRunServiceURL)
}
}

credsOption, err := dgrpc.WithAutoTransportCredentials(false, plaintext, false)
cli.NoError(err, "unable to create auto transport credentials option")

fmt.Printf("Connecting to remote build server at %s ...\n", cloudRunServiceURL)
conn, err := dgrpc.NewClientConn(cloudRunServiceURL, credsOption)
cli.NoError(err, "unable to create external client")
defer func() {
if err := conn.Close(); err != nil {
zlog.Error("unable to close connection gracefully", zap.Error(err))
}
}()

fmt.Printf("Reading file: %s ...\n", filepath)
b, err := os.ReadFile(filepath)
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
}

fmt.Println("Sending build request ...")
client := pbbuild.NewBuildServiceClient(conn)
buildResponse, err := client.Build(context.Background(), &pbbuild.BuildRequest{
SourceCode: b,
Env: envs,
CollectPattern: spkgName,
})
if err != nil {
return fmt.Errorf("failed to build: %w", err)
}

for {
resp, err := buildResponse.Recv()
if err != nil {
return fmt.Errorf("failed to build: %w", err)
}

if resp == nil {
break
}

if resp.Error != "" {
if resp.Logs != "" {
fmt.Print(resp.Logs)
}

return fmt.Errorf("failed to build: %s", resp.Error)
}

if len(resp.Artifacts) != 0 {
// printout the rest of the logs, if there are any
if resp.Logs != "" {
fmt.Print(resp.Logs)
}
for _, artifact := range resp.Artifacts {
err = os.WriteFile(artifact.Filename, artifact.Content, 0644)
if err != nil {
return fmt.Errorf("failed to write file: %w", err)
}
}
break
}

// print out the logs as we get them, if there are any
if resp.Logs != "" {
fmt.Print(resp.Logs)
}
}

fmt.Println("All done!")
return nil
}
16 changes: 10 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/streamingfast/dauth v0.0.0-20240219205130-bfe428489338
github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c
github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1
github.com/streamingfast/dgrpc v0.0.0-20240219152146-57bb131c39ca
github.com/streamingfast/dgrpc v0.0.0-20240423143010-f36784700c9a
github.com/streamingfast/dstore v0.1.1-0.20240311181234-470a7a84936f
github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091
github.com/streamingfast/pbgo v0.0.6-0.20231120172814-537d034aad5e
Expand Down Expand Up @@ -64,32 +64,36 @@ require (
github.com/streamingfast/shutter v1.5.0
github.com/streamingfast/substreams-sdk-go v0.0.0-20240110154316-5fb21a7a330b
github.com/streamingfast/substreams-sink-sql v1.0.1-0.20231127153906-acf5f3e34330
github.com/streamingfast/substreams/remotebuild v0.0.0-20240605005322-fb56102ba033
github.com/test-go/testify v1.1.4
github.com/tetratelabs/wazero v1.7.1
github.com/tidwall/pretty v1.2.1
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0
go.opentelemetry.io/otel v1.24.0
go.opentelemetry.io/otel/trace v1.24.0
go.uber.org/atomic v1.10.0
golang.org/x/mod v0.12.0
golang.org/x/mod v0.17.0
golang.org/x/net v0.22.0
golang.org/x/oauth2 v0.18.0
google.golang.org/grpc v1.64.0
gopkg.in/yaml.v2 v2.4.0
)

// replace github.com/streamingfast/substreams/remotebuild v0.0.0-20240604193227-fe8c0b6697e4 => /Users/eduardvoiculescu/git/streamingfast/substreams/remotebuild

require (
connectrpc.com/grpchealth v1.3.0 // indirect
connectrpc.com/otelconnect v0.7.0 // indirect
github.com/bits-and-blooms/bitset v1.12.0 // indirect
github.com/bobg/go-generics/v2 v2.1.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/bobg/go-generics/v2 v2.2.2 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/sercand/kuberesolver/v5 v5.1.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.uber.org/goleak v1.3.0 // indirect
golang.org/x/time v0.5.0 // indirect
Expand Down Expand Up @@ -214,8 +218,8 @@ require (
go.opentelemetry.io/otel/sdk v1.23.1 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1
golang.org/x/sync v0.6.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
Expand Down
Loading

0 comments on commit f5da2d3

Please sign in to comment.