Tiltfile 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. # This Tiltfile contains the deployment and build config for the Wormhole devnet.
  2. #
  3. # We use Buildkit cache mounts and careful layering to avoid unnecessary rebuilds - almost
  4. # all source code changes result in small, incremental rebuilds. Dockerfiles are written such
  5. # that, for example, changing the contract source code won't cause Solana itself to be rebuilt.
  6. #
  7. # Graph of dependencies between Dockerfiles, image refs and k8s StatefulSets:
  8. #
  9. # Dockerfile Image ref StatefulSet
  10. # +------------------------------------------------------------------------------+
  11. # rust-1.*
  12. # + +-----------------+
  13. # +-> Dockerfile.agent +-> solana-agent +--------+-----> | [agent] |
  14. # | | +--> | guardian-N |
  15. # +-> solana/Dockerfile +-> solana-contract +---+ | | +-- --------------+
  16. # | | |
  17. # | | |
  18. # | | | +-----------------+
  19. # +--|-----> | solana-devnet |
  20. # golang:1.* +-----> | [setup] |
  21. # + | +-----------------+
  22. # +-> bridge/Dockerfile +-> guardiand-image +---------+
  23. #
  24. #
  25. # node:lts-alpine
  26. # + +-----------------+
  27. # +-> ethereum/Dockerfile +-> eth-node +------------------> | eth-devnet |
  28. # +-----------------+
  29. #
  30. load('ext://namespace', 'namespace_inject', 'namespace_create')
  31. # Runtime configuration
  32. config.define_string("num", False, "Number of guardian nodes to run")
  33. # You do not usually need to set this argument - this argument is for debugging only. If you do use a different
  34. # namespace, note that the "wormhole" namespace is hardcoded in the e2e test and don't forget specifying the argument
  35. # when running "tilt down".
  36. #
  37. config.define_string("namespace", False, "Kubernetes namespace to use")
  38. cfg = config.parse()
  39. num_guardians = int(cfg.get("num", "5"))
  40. namespace = cfg.get("namespace", "wormhole")
  41. # namespace
  42. namespace_create(namespace)
  43. def k8s_yaml_with_ns(objects):
  44. return k8s_yaml(namespace_inject(objects, namespace))
  45. # protos
  46. local_resource(
  47. name = "proto-gen",
  48. deps = ["./proto", "./generate-protos.sh"],
  49. cmd = "./generate-protos.sh",
  50. )
  51. # bridge
  52. docker_build(
  53. ref = "guardiand-image",
  54. context = "bridge",
  55. dockerfile = "bridge/Dockerfile",
  56. )
  57. def build_bridge_yaml():
  58. bridge_yaml = read_yaml_stream("devnet/bridge.yaml")
  59. for obj in bridge_yaml:
  60. if obj["kind"] == "StatefulSet" and obj["metadata"]["name"] == "guardian":
  61. obj["spec"]["replicas"] = num_guardians
  62. container = obj["spec"]["template"]["spec"]["containers"][0]
  63. if container["name"] != "guardiand":
  64. fail("container 0 is not guardiand")
  65. container["command"] += ["--devNumGuardians", str(num_guardians)]
  66. return encode_yaml_stream(bridge_yaml)
  67. k8s_yaml_with_ns(build_bridge_yaml())
  68. k8s_resource("guardian", resource_deps=["proto-gen", "solana-devnet"], port_forwards=[
  69. port_forward(6060, name="Debug/Status Server [:6060]"),
  70. ])
  71. # publicRPC proxy that allows grpc over http1, for local development
  72. k8s_yaml_with_ns("./devnet/envoy-proxy.yaml")
  73. k8s_resource("envoy-proxy", resource_deps=["guardian"],
  74. objects=['envoy-proxy:ConfigMap:wormhole'],
  75. port_forwards=[
  76. port_forward(8080, name="gRPC proxy for guardian's publicRPC data [:8080]"),
  77. port_forward(9901, name="gRPC proxy admin [:9901]"), # for proxy debugging
  78. ])
  79. # solana agent and cli (runs alongside bridge)
  80. docker_build(
  81. ref="solana-agent",
  82. context=".",
  83. only=["./proto", "./solana"],
  84. dockerfile="Dockerfile.agent",
  85. # Ignore target folders from local (non-container) development.
  86. ignore = ["./solana/target", "./solana/agent/target", "./solana/cli/target"],
  87. )
  88. # solana smart contract
  89. docker_build(
  90. ref = "solana-contract",
  91. context = "solana",
  92. dockerfile = "solana/Dockerfile",
  93. )
  94. # solana local devnet
  95. k8s_yaml_with_ns("devnet/solana-devnet.yaml")
  96. k8s_resource("solana-devnet", port_forwards=[
  97. port_forward(8899, name="Solana RPC [:8899]"),
  98. port_forward(8900, name="Solana WS [:8900]"),
  99. port_forward(9000, name="Solana PubSub [:9000]"),
  100. ])
  101. # eth devnet
  102. docker_build(
  103. ref = "eth-node",
  104. context = "./ethereum",
  105. dockerfile = "./ethereum/Dockerfile",
  106. # ignore local node_modules (in case they're present)
  107. ignore = ["./ethereum/node_modules"],
  108. # sync external scripts for incremental development
  109. # (everything else needs to be restarted from scratch for determinism)
  110. #
  111. # This relies on --update-mode=exec to work properly with a non-root user.
  112. # https://github.com/tilt-dev/tilt/issues/3708
  113. live_update = [
  114. sync("./ethereum/src", "/home/node/app/src"),
  115. ],
  116. )
  117. k8s_yaml_with_ns("devnet/eth-devnet.yaml")
  118. k8s_resource("eth-devnet", port_forwards=[
  119. port_forward(8545, name="Ganache RPC [:8545]")
  120. ])
  121. # web frontend
  122. docker_build(
  123. ref = "web",
  124. context = "./web",
  125. dockerfile = "./web/Dockerfile",
  126. ignore = ["./web/node_modules"],
  127. live_update = [
  128. sync("./web/src", "/home/node/app/src"),
  129. sync("./web/public", "/home/node/app/public"),
  130. sync("./web/contracts", "/home/node/app/contracts"),
  131. ],
  132. )
  133. k8s_yaml_with_ns("devnet/web.yaml")
  134. k8s_resource("web", port_forwards=[
  135. port_forward(3000, name="Experimental Web UI [:3000]")
  136. ])
  137. # explorer web app
  138. docker_build(
  139. ref = "explorer",
  140. context = "./explorer",
  141. dockerfile = "./explorer/Dockerfile",
  142. ignore = ["./explorer/node_modules"],
  143. live_update = [
  144. sync("./explorer/src", "/home/node/app/src"),
  145. sync("./explorer/public", "/home/node/app/public"),
  146. ],
  147. )
  148. k8s_yaml_with_ns("devnet/explorer.yaml")
  149. k8s_resource("explorer",
  150. resource_deps=["envoy-proxy"],
  151. port_forwards=[
  152. port_forward(8001, name="Explorer Web UI [:8001]")
  153. ]
  154. )
  155. # terra devnet
  156. docker_build(
  157. ref = "terra-image",
  158. context = "./terra/devnet",
  159. dockerfile = "terra/devnet/Dockerfile",
  160. )
  161. docker_build(
  162. ref = "terra-contracts",
  163. context = "./terra",
  164. dockerfile = "./terra/Dockerfile",
  165. )
  166. k8s_yaml_with_ns("devnet/terra-devnet.yaml")
  167. k8s_resource(
  168. "terra-lcd",
  169. port_forwards=[port_forward(1317, name="Terra LCD interface [:1317]")]
  170. )
  171. k8s_resource(
  172. "terra-terrad",
  173. port_forwards=[port_forward(26657, name="Terra RPC [:26657]")]
  174. )