release.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. releaseCmd := getReleaseCommandFromRelease(client, stackName, projectID, clusterID)
  14. if release == nil && releaseCmd == "" {
  15. return nil, "", nil
  16. } else if release != nil && release.Run != nil {
  17. finalCmd = *release.Run
  18. } else {
  19. finalCmd = releaseCmd
  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": CopyEnv(env),
  33. }
  34. helm_values["paused"] = false
  35. config.Values = convertMap(helm_values).(map[string]interface{})
  36. rawConfig := make(map[string]any)
  37. err := mapstructure.Decode(config, &rawConfig)
  38. if err != nil {
  39. return nil, "", fmt.Errorf("could not decode config for release: %w", err)
  40. }
  41. return &switchboardTypes.Resource{
  42. Name: fmt.Sprintf("%s-r", stackName),
  43. DependsOn: []string{"get-env", buildResourceName, pushResourceName},
  44. Source: map[string]any{
  45. "name": "job",
  46. },
  47. Target: map[string]any{
  48. "app_name": fmt.Sprintf("%s-r", stackName),
  49. "namespace": fmt.Sprintf("porter-stack-%s", stackName),
  50. },
  51. Config: rawConfig,
  52. }, finalCmd, nil
  53. }
  54. func getReleaseCommandFromRelease(client *api.Client, stackName string, projectID uint, clusterID uint) string {
  55. namespace := fmt.Sprintf("porter-stack-%s", stackName)
  56. releaseName := fmt.Sprintf("%s-r", stackName)
  57. release, err := client.GetRelease(
  58. context.Background(),
  59. projectID,
  60. clusterID,
  61. namespace,
  62. releaseName,
  63. )
  64. if err != nil || release == nil || release.Config == nil {
  65. return ""
  66. }
  67. containerMap, err := deploy.GetNestedMap(release.Config, "container")
  68. if err == nil {
  69. if command, ok := containerMap["command"]; ok {
  70. if commandString, ok := command.(string); ok {
  71. return commandString
  72. }
  73. }
  74. }
  75. return ""
  76. }
  77. func convertMap(m interface{}) interface{} {
  78. switch m := m.(type) {
  79. case map[string]interface{}:
  80. for k, v := range m {
  81. m[k] = convertMap(v)
  82. }
  83. case map[interface{}]interface{}:
  84. result := map[string]interface{}{}
  85. for k, v := range m {
  86. result[k.(string)] = convertMap(v)
  87. }
  88. return result
  89. case []interface{}:
  90. for i, v := range m {
  91. m[i] = convertMap(v)
  92. }
  93. }
  94. return m
  95. }