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