release.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package stack
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/mitchellh/mapstructure"
  6. api "github.com/porter-dev/porter/api/client"
  7. "github.com/porter-dev/porter/cli/cmd/deploy"
  8. "github.com/porter-dev/porter/internal/integrations/preview"
  9. switchboardTypes "github.com/porter-dev/switchboard/pkg/types"
  10. )
  11. func createReleaseResource(client *api.Client, release *App, stackName, buildResourceName, pushResourceName string, projectID, clusterID uint, env map[string]string) (*switchboardTypes.Resource, string, error) {
  12. var finalCmd string
  13. if release != nil && release.Run != nil {
  14. finalCmd = *release.Run
  15. } else {
  16. finalCmd = getReleaseCommandFromRelease(client, stackName, projectID, clusterID)
  17. if finalCmd == "" {
  18. return nil, "", nil
  19. }
  20. }
  21. config := &preview.ApplicationConfig{}
  22. config.Build.Method = "registry"
  23. config.Build.Image = fmt.Sprintf("{ .%s.image }", buildResourceName)
  24. config.Build.Env = CopyEnv(env)
  25. config.WaitForJob = true
  26. helm_values := make(map[string]interface{})
  27. if release != nil && release.Config != nil {
  28. helm_values = release.Config
  29. }
  30. helm_values["container"] = map[string]interface{}{
  31. "command": finalCmd,
  32. "env": map[string]interface{}{
  33. "normal": CopyEnv(env),
  34. },
  35. }
  36. helm_values["paused"] = false
  37. config.Values = convertMap(helm_values).(map[string]interface{})
  38. rawConfig := make(map[string]any)
  39. err := mapstructure.Decode(config, &rawConfig)
  40. if err != nil {
  41. return nil, "", fmt.Errorf("could not decode config for release: %w", err)
  42. }
  43. return &switchboardTypes.Resource{
  44. Name: fmt.Sprintf("%s-r", stackName),
  45. DependsOn: []string{"get-env", buildResourceName, pushResourceName},
  46. Source: map[string]any{
  47. "name": "job",
  48. },
  49. Target: map[string]any{
  50. "app_name": fmt.Sprintf("%s-r", stackName),
  51. "namespace": fmt.Sprintf("porter-stack-%s", stackName),
  52. },
  53. Config: rawConfig,
  54. }, finalCmd, nil
  55. }
  56. func getReleaseCommandFromRelease(client *api.Client, stackName string, projectID uint, clusterID uint) string {
  57. namespace := fmt.Sprintf("porter-stack-%s", stackName)
  58. releaseName := fmt.Sprintf("%s-r", stackName)
  59. release, err := client.GetRelease(
  60. context.Background(),
  61. projectID,
  62. clusterID,
  63. namespace,
  64. releaseName,
  65. )
  66. if err != nil || release == nil || release.Config == nil {
  67. return ""
  68. }
  69. containerMap, err := deploy.GetNestedMap(release.Config, "container")
  70. if err == nil {
  71. if command, ok := containerMap["command"]; ok {
  72. if commandString, ok := command.(string); ok {
  73. return commandString
  74. }
  75. }
  76. }
  77. return ""
  78. }
  79. func convertMap(m interface{}) interface{} {
  80. switch m := m.(type) {
  81. case map[string]interface{}:
  82. for k, v := range m {
  83. m[k] = convertMap(v)
  84. }
  85. case map[interface{}]interface{}:
  86. result := map[string]interface{}{}
  87. for k, v := range m {
  88. result[k.(string)] = convertMap(v)
  89. }
  90. return result
  91. case []interface{}:
  92. for i, v := range m {
  93. m[i] = convertMap(v)
  94. }
  95. }
  96. return m
  97. }