Skip to content

Commit

Permalink
Merge pull request #53 from comrade-coop/xx-development-env
Browse files Browse the repository at this point in the history
Improve development environment + minor fixes
  • Loading branch information
bojidar-bg authored Oct 24, 2024
2 parents 0541bac + 300e0d3 commit 4bbf371
Show file tree
Hide file tree
Showing 68 changed files with 1,606 additions and 1,441 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ indent_size = 2
[*.{yml,yaml}]
indent_style = space
indent_size = 2

[Tiltfile]
indent_style = space
indent_size = 4
22 changes: 22 additions & 0 deletions .github/workflows/check-py.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Check Python code

on:
push:
paths:
- '**/Tiltfile'
- '**.py'
- '.github/workflows/check-py.yml'

jobs:
check-fmt:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check format
uses: psf/black@stable
with:
options: '--line-length 100 --include Tiltfile --check'
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
path = contracts/lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
[submodule "constellation"]
path = constellation
path = deploy/constellation/constellation-src
url = https://github.com/comrade-coop/constellation
44 changes: 32 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,73 @@

## common: ##

FROM docker.io/library/golang:1.22.6@sha256:367bb5295d3103981a86a572651d8297d6973f2ec8b62f716b007860e22cbc25 as build-common
# 1.21-bookworm
FROM docker.io/library/golang:1.23.1-bookworm@sha256:1a5326b07cbab12f4fd7800425f2cf25ff2bd62c404ef41b56cb99669a710a83 as build-dependencies

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y protobuf-compiler libgpgme-dev && rm -rf /var/lib/apt/lists/*
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 && go install github.com/ethereum/go-ethereum/cmd/abigen@v1.13.3
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 && go install github.com/ethereum/go-ethereum/cmd/abigen@v1.14.9

FROM build-dependencies AS build-common

WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download && go mod verify
RUN --mount=type=cache,target=/root/.cache/go-build go mod download && go mod verify

COPY pkg ./pkg

FROM docker.io/debian@sha256:2bc5c236e9b262645a323e9088dfa3bb1ecb16cc75811daf40a23a824d665be9 as run-common
# bookworm-slim, bookworm-20231120-slim matching golang:1.21-bookworm
FROM docker.io/debian:bookworm-20240904-slim@sha256:a629e796d77a7b2ff82186ed15d01a493801c020eed5ce6adaa2704356f15a1c as run-common
# matching golang:1.23.1-bookworm above

RUN apt-get update && apt-get install -y libgpgme11 curl jq && rm -rf /var/lib/apt/lists/*

## p2p-helper: ##

FROM build-common as build-p2p-helper
FROM build-common AS build-p2p-helper

COPY cmd/ipfs-p2p-helper ./cmd/ipfs-p2p-helper
RUN --mount=type=cache,target=/root/.cache/go-build go build -v -o /usr/local/bin/ipfs-p2p-helper ./cmd/ipfs-p2p-helper

FROM run-common as p2p-helper
FROM run-common AS p2p-helper

COPY --from=build-p2p-helper /usr/local/bin/ipfs-p2p-helper /usr/local/bin/ipfs-p2p-helper

ENTRYPOINT ["ipfs-p2p-helper"]

FROM run-common AS p2p-helper-copy-local

COPY ./bin/ipfs-p2p-helper /usr/local/bin/ipfs-p2p-helper

ENTRYPOINT ["ipfs-p2p-helper"]

## server: ##

FROM build-common as build-server
FROM build-common AS build-server

COPY cmd/tpodserver ./cmd/tpodserver
RUN --mount=type=cache,target=/root/.cache/go-build go build -v -o /usr/local/bin/tpodserver ./cmd/tpodserver
# RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=bind,source=.,target=/app go build -v -o /usr/local/bin/tpodserver ./cmd/tpodserver

FROM run-common as server
FROM run-common AS server

COPY --from=build-server /usr/local/bin/tpodserver /usr/local/bin/tpodserver

ENTRYPOINT ["tpodserver"]

FROM run-common AS server-copy-local

COPY ./bin/tpodserver /usr/local/bin/tpodserver

ENTRYPOINT ["tpodserver"]

## autoscaler: ##

FROM build-common as build-autoscaler
FROM build-common AS build-autoscaler

COPY autoscaler ./autoscaler
RUN --mount=type=cache,target=/root/.cache/go-build go build -v -o /usr/local/bin/autoscaler ./autoscaler

FROM run-common as autoscaler
FROM run-common AS autoscaler

COPY --from=build-autoscaler /usr/local/bin/autoscaler /usr/local/bin/autoscaler

Expand All @@ -72,3 +86,9 @@ FROM run-common as tpod-proxy
COPY --from=build-tpod-proxy /usr/local/bin/tpod-proxy /usr/local/bin/tpod-proxy

ENTRYPOINT ["tpod-proxy"]

FROM run-common AS tpod-proxy-copy-local

COPY ./bin/proxy /usr/local/bin/tpod-proxy

ENTRYPOINT ["tpod-proxy"]
29 changes: 18 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ Before running the various tests, Make sure the following dependencies are insta
- **[kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)**: The Kubernetes command-line tool for managing Kubernetes clusters.
- **[docker](https://docs.docker.com/engine/install/)**: platform for developing, shipping, and running applications using containerization.
- **[jq](https://jqlang.github.io/jq/)**: lightweight and flexible command-line JSON processor.
- **[minikube](https://minikube.sigs.k8s.io/docs/start/)**: tool that runs a single-node Kubernetes cluster locally.
- **[kind](https://kind.sigs.k8s.io/docs/user/quick-start/)**: tool that runs a single-node Kubernetes cluster locally.
- **[ctlptl](https://github.com/tilt-dev/ctlptl/)**: An utility for declaratively setting up local Kubernetes clusters.
- **[tilt](https://docs.tilt.dev/install.html)**: A toolkit automating the process of setting up a new local development cluster.
- **[helm](https://helm.sh/)**: package manager for Kubernetes
- **[helmfile](https://github.com/helmfile/helmfile)**: declarative configuration tool for Helm.
- **[forge, cast, anvil](https://github.com/foundry-rs/foundry)**: tools for building Ethereum-based applications.
- **[forge, cast, anvil](https://github.com/foundry-rs/foundry)**: tools for building Ethereum-based applications. <!-- TODO: Move to container -->
- **[ipfs](https://docs.ipfs.tech/install/command-line/#install-official-binary-distributions)**: The InterPlanetary File System
- **[constellation](https://docs.edgeless.systems/constellation/getting-started/first-steps-local)**: Constellation is a Kubernetes engine that provides a secure and confidential way to run Kubernetes clusters. (Needed in `test/e2e/constellation`).

Expand All @@ -55,30 +57,35 @@ npm i && turbo sync
```
> Rerun `turbo sync` whenever you change files under the `proto/` and `contracts/` folders.
To start a local environment for e.g. integration-testing or evaluating the project, you can use the end-to-end tests in the `test/e2e` folder.
To start a local environment for e.g. integration-testing or evaluating the project, you can use `tilt` with Tiltfile in the `test/e2e` folder.

Typical development involves running the minikube end-to-end test, which can be done using the following command:
You can use it, for example, by running the following commands:

```bash
./test/e2e/minikube/run-test.sh
# Create a kind cluster:
ctlptl create cluster kind --registry=ctlptl-registry --kubernetes-version=v1.31.0
# Start tilt and run the nginx test:
tilt up -- --include ./test/e2e/nginx/Tiltfile
```

The command, after all dependencies are met, will proceed to start a local docker registry and test ethereum node, build and upload the project to them, then spin up a minikube cluster and deploy all necessary prerequisites into it, and finally deploying a pod from a [manifest file](spec/MANIFEST.md) into the cluster and then querying it over HTTP. It should display the curl command used to query the pod, and you should be able to use it yourself after the script is finished.
The first command will spin up a kind cluster with a local registry. Then, the second command will, after checking that any additional dependencies are met, then deploy all necessary prerequisites into local cluster, and finally deploying a pod from a [manifest file](spec/MANIFEST.md) into the cluster. <!-- TODO and then querying it over HTTP. It should display the curl command used to query the pod, and you should be able to use it yourself after the script is finished. -->

<!-- TODO
In addition, once you have started the minikube end-to-end test, you can also run the web UI test, which presents a sample interface that publishers can use to deploy a predefined pod template onto the minikube cluster / provider directly from their web browser.
```bash
turbo dev
```
``` -->

Once you are done playing around with the tests, simply run the following command to delete and stop the minikube cluster:
Once you are done playing around with the test, run the following commands to clean up:

```bash
test/e2e/minikube/run-test.sh teardown
# Clean up the local cluster:
tilt down -- --include ./test/e2e/nginx/Tiltfile
# Delete up the local cluster:
ctlptl create delete kind
```

(or alternatively, pass `teardown full` to also stop any local docker containers used by the test)

<!-- Note that while committing generated files is foreign to Nodejs/NPM, it's the usual way of life in the Go ecosystem, as packages are directly cloned from git rather than downloaded from the package manager. Here we are committing both in order to not require forge/protoc for JavaScript development when it's optional for Go development. -->

## Contributing
Expand Down
30 changes: 30 additions & 0 deletions Tiltfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- mode: Python -*-
# SPDX-License-Identifier: GPL-3.0


config.define_string_list("include")
config.define_string("allow-context")
config.define_bool("deploy-stack")
cfg = config.parse()

if "allow-context" in cfg:
allow_k8s_contexts(cfg["allow-context"])

load(
"./deploy/Tiltfile",
"apocryph_resource",
"apocryph_build_with_builder",
"deploy_apocryph_stack",
"deploy_apocryph_local",
)

if cfg.get("deploy-stack", True):
apocryph_build_with_builder()
deploy_apocryph_stack()
deploy_apocryph_local()
else:
apocryph_build_with_builder(skip_images=True)
deploy_apocryph_local(resource_deps=[])

for f in cfg.get("include", []):
load_dynamic(f)
36 changes: 30 additions & 6 deletions cmd/trustedpods/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/rand"
"fmt"
"math/big"
"os"
"path/filepath"

"github.com/comrade-coop/apocryph/pkg/abi"
Expand Down Expand Up @@ -187,12 +188,11 @@ var deployPodCmd = &cobra.Command{
}
}

ctrdClient, err := ipcr.GetContainerdClient("k8s.io")
if err != nil {
return err
}

if uploadImages {
ctrdClient, err := ipcr.GetContainerdClient("k8s.io")
if err != nil {
return err
}
err = publisher.UploadImages(cmd.Context(), ctrdClient, ipfsApi, pod, deployment)
if err != nil {
return err
Expand Down Expand Up @@ -254,7 +254,7 @@ var deletePodCmd = &cobra.Command{
Use: fmt.Sprintf("delete [%s|deployment.yaml]", publisher.DefaultPodFile),
Aliases: []string{"undeploy"},
Short: "Delete a pod from a local deployment",
Args: cobra.MaximumNArgs(1),
Args: cobra.MaximumNArgs(2),
GroupID: "main",
RunE: func(cmd *cobra.Command, args []string) error {
_, deploymentFile, _, deployment, err := publisher.ReadPodAndDeployment(args, manifestFormat, deploymentFormat)
Expand Down Expand Up @@ -300,6 +300,27 @@ var deletePodCmd = &cobra.Command{
},
}

var podNamespaceCmd = &cobra.Command{
Use: fmt.Sprintf("namespace [%s|deployment.yaml]", publisher.DefaultPodFile),
Short: "Get a pod's expected namespace in kubernetes",
Long: "Temporary command, may be removed once/if namespaces are implemented differently.",
GroupID: "lowlevel",
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
_, _, _, deployment, err := publisher.ReadPodAndDeployment(args, manifestFormat, deploymentFormat)
if err != nil {
return err
}
configureDeployment(deployment)

ns := pbcon.NamespaceFromTokenParts(common.BytesToAddress(deployment.Payment.PublisherAddress), common.Hash(deployment.Payment.PodID))

_, err = fmt.Fprintln(os.Stdout, ns)

return err
},
}

func init() {
podCmd.AddCommand(deployPodCmd)
podCmd.AddCommand(deletePodCmd)
Expand All @@ -313,4 +334,7 @@ func init() {
deletePodCmd.Flags().AddFlagSet(deploymentFlags)
deletePodCmd.Flags().AddFlagSet(syncFlags)

podCmd.AddCommand(podNamespaceCmd)
podNamespaceCmd.Flags().AddFlagSet(deploymentFlags)
podNamespaceCmd.Flags().AddFlagSet(fundFlags)
}
9 changes: 6 additions & 3 deletions cmd/trustedpods/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ var _ = func() error {

podFlags.StringVar(&manifestFormat, "format", "", fmt.Sprintf("Manifest format. One of %v (leave empty to auto-detect)", pb.FormatNames))

deploymentFlags.StringVar(&manifestFormat, "deployment-format", "", fmt.Sprintf("Deployment format. One of %v (leave empty to auto-detect)", pb.FormatNames))
deploymentFlags.StringVar(&deploymentFormat, "deployment-format", "", fmt.Sprintf("Deployment format. One of %v (leave empty to auto-detect)", pb.FormatNames))
deploymentFlags.StringVar(&providerPeer, "provider", "", "provider peer id")
deploymentFlags.StringVar(&providerEthAddress, "provider-eth", "", "provider public address")
deploymentFlags.Int64Var(&expirationOffset, "token-expiration", 10, "authentication token expires after token-expiration seconds (expired after 10 seconds by default)")
deploymentFlags.Int64Var(&expirationOffset, "token-expiration", 60, "authentication token expires after token-expiration seconds (expires after 1 minute by default) (note: might need higher values with providers with out-of-sync clocks)")
deploymentFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed")
deploymentFlags.BoolVar(&authorize, "authorize", false, "Create a key pair for the application and authorize the returned addresses to control the payment channel")
deploymentFlags.BoolVar(&verify, "verify", false, "verify the pod images (requires certificate-identity & certificate-oidc-issuer flags)")
Expand Down Expand Up @@ -100,7 +100,9 @@ var _ = func() error {
fundFlags.Int64Var(&unlockTime, "unlock-time", 5*60, "time for unlocking tokens (in seconds)")

syncFlags.AddFlag(uploadFlags.Lookup("ipfs"))
syncFlags.StringVar(&publisherKey, "ethereum-key", "", "account string (private key | http[s]://clef#account | /keystore#account | account (in default keystore))")
syncFlags.AddFlag(fundFlags.Lookup("ethereum-key"))
syncFlags.AddFlag(fundFlags.Lookup("ethereum-rpc"))
syncFlags.AddFlag(fundFlags.Lookup("pod-id"))

registryFlags.StringVar(&ipfsApi, "ipfs", "/ip4/127.0.0.1/tcp/5001", "multiaddr where the ipfs/kubo api can be accessed")
registryFlags.StringVar(&registryContractAddress, "registry-contract", "", "registry contract address")
Expand All @@ -116,6 +118,7 @@ var _ = func() error {
registryFlags.StringVar(&tableId, "id", "", "table id")
registryFlags.StringVar(&region, "region", "", "filter providers by region, Ex: us-east-8")
registryFlags.AddFlag(fundFlags.Lookup("ethereum-key"))
registryFlags.AddFlag(fundFlags.Lookup("ethereum-rpc"))

return nil
}()
Expand Down
1 change: 1 addition & 0 deletions deploy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/keys/
Loading

0 comments on commit 4bbf371

Please sign in to comment.