target.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package gcs
  14. import (
  15. "fmt"
  16. "path"
  17. "strconv"
  18. "strings"
  19. "github.com/sirupsen/logrus"
  20. "k8s.io/test-infra/prow/kube"
  21. "k8s.io/test-infra/prow/pod-utils/downwardapi"
  22. )
  23. // PathForSpec determines the GCS path prefix for files uploaded
  24. // for a specific job spec
  25. func PathForSpec(spec *downwardapi.JobSpec, pathSegment RepoPathBuilder) string {
  26. switch spec.Type {
  27. case kube.PeriodicJob, kube.PostsubmitJob:
  28. return path.Join("logs", spec.Job, spec.BuildID)
  29. case kube.PresubmitJob:
  30. return path.Join("pr-logs", "pull", pathSegment(spec.Refs.Org, spec.Refs.Repo), strconv.Itoa(spec.Refs.Pulls[0].Number), spec.Job, spec.BuildID)
  31. case kube.BatchJob:
  32. return path.Join("pr-logs", "pull", "batch", spec.Job, spec.BuildID)
  33. default:
  34. logrus.Fatalf("unknown job spec type: %v", spec.Type)
  35. }
  36. return ""
  37. }
  38. // AliasForSpec determines the GCS path aliases for a job spec
  39. func AliasForSpec(spec *downwardapi.JobSpec) string {
  40. switch spec.Type {
  41. case kube.PeriodicJob, kube.PostsubmitJob, kube.BatchJob:
  42. return ""
  43. case kube.PresubmitJob:
  44. return path.Join("pr-logs", "directory", spec.Job, fmt.Sprintf("%s.txt", spec.BuildID))
  45. default:
  46. logrus.Fatalf("unknown job spec type: %v", spec.Type)
  47. }
  48. return ""
  49. }
  50. // LatestBuildForSpec determines the GCS path for storing the latest
  51. // build id for a job. pathSegment can be nil so callers of this
  52. // helper are not required to choose a path strategy but can still
  53. // get back a result.
  54. func LatestBuildForSpec(spec *downwardapi.JobSpec, pathSegment RepoPathBuilder) []string {
  55. var latestBuilds []string
  56. switch spec.Type {
  57. case kube.PeriodicJob, kube.PostsubmitJob:
  58. latestBuilds = append(latestBuilds, path.Join("logs", spec.Job, "latest-build.txt"))
  59. case kube.PresubmitJob:
  60. latestBuilds = append(latestBuilds, path.Join("pr-logs", "directory", spec.Job, "latest-build.txt"))
  61. // Gubernator expects presubmit tests to upload latest-build.txt
  62. // under the PR-specific directory too.
  63. if pathSegment != nil {
  64. latestBuilds = append(latestBuilds, path.Join("pr-logs", "pull", pathSegment(spec.Refs.Org, spec.Refs.Repo), strconv.Itoa(spec.Refs.Pulls[0].Number), spec.Job, "latest-build.txt"))
  65. }
  66. case kube.BatchJob:
  67. latestBuilds = append(latestBuilds, path.Join("pr-logs", "directory", spec.Job, "latest-build.txt"))
  68. default:
  69. logrus.Errorf("unknown job spec type: %v", spec.Type)
  70. return nil
  71. }
  72. return latestBuilds
  73. }
  74. // RootForSpec determines the root GCS path for storing artifacts about
  75. // the provided job.
  76. func RootForSpec(spec *downwardapi.JobSpec) string {
  77. switch spec.Type {
  78. case kube.PeriodicJob, kube.PostsubmitJob:
  79. return path.Join("logs", spec.Job)
  80. case kube.PresubmitJob, kube.BatchJob:
  81. return path.Join("pr-logs", "directory", spec.Job)
  82. default:
  83. logrus.Errorf("unknown job spec type: %v", spec.Type)
  84. }
  85. return ""
  86. }
  87. // RepoPathBuilder builds GCS path segments and embeds defaulting behavior
  88. type RepoPathBuilder func(org, repo string) string
  89. // NewLegacyRepoPathBuilder returns a builder that handles the legacy path
  90. // encoding where a path will only contain an org or repo if they are non-default
  91. func NewLegacyRepoPathBuilder(defaultOrg, defaultRepo string) RepoPathBuilder {
  92. return func(org, repo string) string {
  93. if org == defaultOrg {
  94. if repo == defaultRepo {
  95. return ""
  96. }
  97. return repo
  98. }
  99. // handle gerrit repo
  100. repo = strings.Replace(repo, "/", "_", -1)
  101. return fmt.Sprintf("%s_%s", org, repo)
  102. }
  103. }
  104. // NewSingleDefaultRepoPathBuilder returns a builder that handles the legacy path
  105. // encoding where a path will contain org and repo for all but one default repo
  106. func NewSingleDefaultRepoPathBuilder(defaultOrg, defaultRepo string) RepoPathBuilder {
  107. return func(org, repo string) string {
  108. if org == defaultOrg && repo == defaultRepo {
  109. return ""
  110. }
  111. // handle gerrit repo
  112. repo = strings.Replace(repo, "/", "_", -1)
  113. return fmt.Sprintf("%s_%s", org, repo)
  114. }
  115. }
  116. // NewExplicitRepoPathBuilder returns a builder that handles the path encoding
  117. // where a path will always have an explicit "org_repo" path segment
  118. func NewExplicitRepoPathBuilder() RepoPathBuilder {
  119. return func(org, repo string) string {
  120. // handle gerrit repo
  121. repo = strings.Replace(repo, "/", "_", -1)
  122. return fmt.Sprintf("%s_%s", org, repo)
  123. }
  124. }