Tiltfile.opencost 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. load('ext://helm_resource', 'helm_resource', 'helm_repo')
  2. load('ext://restart_process', 'docker_build_with_restart')
  3. load('ext://secret', 'secret_create_generic')
  4. def get_docker_platform(arch):
  5. if arch == "arm64":
  6. return "linux/arm64"
  7. else:
  8. return "linux/amd64"
  9. def get_go_arch(arch):
  10. if arch == "arm64":
  11. return "arm64"
  12. else:
  13. return "amd64"
  14. # run_opencost is encapsulated as a function to make import easier for running alongside kubecost.
  15. # The `../opencost` pattern that repeats across this function is to deal with how multiple tilt
  16. # files work - the base directory (`.`) is always relative to the Tiltfile executed and not the
  17. # directory containing this file.
  18. def run_opencost(options):
  19. docker_platform = get_docker_platform(options["arch"])
  20. go_arch = get_go_arch(options["arch"])
  21. is_cloud_integration = options["cloud_integration"] != '' and os.path.exists(options["cloud_integration"])
  22. is_service_key = options["service_key"] != '' and os.path.exists(options["service_key"])
  23. continue_flag = '--continue'
  24. if options["delve_continue"] == False:
  25. continue_flag = ''
  26. # Build and update opencost back end binary when code changes
  27. local_resource(
  28. name='build-costmodel',
  29. dir='.',
  30. cmd='CGO_ENABLED=0 GOOS=linux GOARCH='+go_arch+' go build -o ../opencost/cmd/costmodel/costmodel-tilt ../opencost/cmd/costmodel/main.go',
  31. deps=[
  32. '../opencost/cmd/costmodel/main.go',
  33. '../opencost/pkg',
  34. ],
  35. allow_parallel=True,
  36. )
  37. # Build back end docker container
  38. # If the binary is updated, update the running container and restart binary in dlv
  39. docker_build_with_restart(
  40. ref=options["docker_repo"]+'opencost-costmodel',
  41. context='../opencost',
  42. # remove --continue flag to make dlv wait until debugger is attached to start
  43. entrypoint='/go/bin/dlv exec --listen=:40000 --api-version=2 --headless=true --accept-multiclient --log '+continue_flag+' /app/main',
  44. dockerfile='../opencost/Dockerfile.debug',
  45. platform=docker_platform,
  46. build_args={'binary_path': './cmd/costmodel/costmodel-tilt'},
  47. only=[
  48. 'cmd/costmodel/costmodel-tilt',
  49. 'configs',
  50. 'THIRD_PARTY_LICENSES.txt',
  51. ],
  52. live_update=[
  53. sync('../opencost/cmd/costmodel/costmodel-tilt', '/app/main'),
  54. ],
  55. )
  56. # npm install if package.json changes
  57. local_resource(
  58. name='build-npm-install',
  59. dir='../opencost/ui',
  60. cmd='npm install',
  61. deps=[
  62. '../opencost/ui/package.json',
  63. ],
  64. allow_parallel=True,
  65. )
  66. # Build FE locally when code changes
  67. local_resource(
  68. name='build-ui',
  69. dir='../opencost/ui',
  70. cmd='npx parcel build src/index.html',
  71. deps=[
  72. '../opencost/ui/src',
  73. '../opencost/ui/package.json',
  74. ],
  75. allow_parallel=True,
  76. resource_deps=['build-npm-install'],
  77. )
  78. # update container when relevant files change
  79. docker_build(
  80. ref=options["docker_repo"]+'opencost-ui',
  81. context='../opencost/ui',
  82. dockerfile='../opencost/ui/Dockerfile.debug',
  83. only=[
  84. 'dist',
  85. 'nginx.conf',
  86. 'default.nginx.conf.template',
  87. 'docker-entrypoint.sh',
  88. ],
  89. live_update=[
  90. sync('../opencost/ui/dist', '/var/www'),
  91. ],
  92. )
  93. values_set = [
  94. 'opencost.ui.image.fullImageName='+options["docker_repo"]+'opencost-ui',
  95. 'opencost.exporter.image.fullImageName='+options["docker_repo"]+'opencost-costmodel',
  96. 'opencost.prometheus.internal.namespaceName='+k8s_namespace(),
  97. 'opencost.exporter.debugPort=40000',
  98. ]
  99. if is_cloud_integration:
  100. values_set.append('opencost.cloudIntegrationSecret=cloud-integration')
  101. values_set.append('opencost.cloudCost.enabled=true')
  102. else:
  103. values_set.append('opencost.cloudCost.enabled=false')
  104. if is_cloud_integration:
  105. secret_create_generic(
  106. name='cloud-integration',
  107. namespace=k8s_namespace(),
  108. from_file=options["cloud_integration"],
  109. secret_type=None,
  110. from_env_file=None
  111. )
  112. if is_service_key:
  113. secret_create_generic(
  114. name='service-key',
  115. namespace=k8s_namespace(),
  116. from_file=options["service_key"],
  117. secret_type=None,
  118. from_env_file=None
  119. )
  120. # build yaml for deployment to k8s
  121. yaml = helm(
  122. '../opencost-helm-chart/charts/opencost',
  123. name='opencost',
  124. values=[options["helm_values"]],
  125. set=values_set
  126. )
  127. k8s_yaml(yaml) # put resulting yaml into k8s
  128. port_forwards = [
  129. options['port_costmodel']+':9003',
  130. options['port_ui']+':9090',
  131. options['port_debug']+':40000',
  132. '8081:8081', # MCP server port
  133. ]
  134. k8s_resource(workload='opencost', port_forwards=port_forwards)
  135. helm_repo('prometheus-community', 'https://prometheus-community.github.io/helm-charts')
  136. helm_resource(
  137. name='prometheus',
  138. chart='prometheus-community/prometheus',
  139. resource_deps=['prometheus-community'])
  140. k8s_resource(workload='prometheus', port_forwards=[options['port_prometheus']+':9090'])
  141. local_resource(
  142. name='costmodel-test',
  143. dir='../opencost',
  144. cmd='go test ./...',
  145. deps=[
  146. './pkg',
  147. ],
  148. allow_parallel=True,
  149. resource_deps=['opencost'], # run tests after build to speed up deployment
  150. )