sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/crier/reporters/gcs/util/util.go (about)

     1  /*
     2  Copyright 2020 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 util
    18  
    19  import (
    20  	"encoding/json"
    21  	"errors"
    22  	"fmt"
    23  	"strings"
    24  
    25  	"github.com/GoogleCloudPlatform/testgrid/metadata"
    26  	prowv1 "sigs.k8s.io/prow/pkg/apis/prowjobs/v1"
    27  	"sigs.k8s.io/prow/pkg/config"
    28  	"sigs.k8s.io/prow/pkg/gcsupload"
    29  	"sigs.k8s.io/prow/pkg/pod-utils/downwardapi"
    30  )
    31  
    32  func GetJobDestination(cfg config.Getter, pj *prowv1.ProwJob) (bucket, dir string, err error) {
    33  	// We can't divine a destination for jobs that don't have a build ID, so don't try.
    34  	gc, err := gcsConfig(cfg, pj)
    35  	if err != nil {
    36  		return "", "", err
    37  	}
    38  	ps := downwardapi.NewJobSpec(pj.Spec, pj.Status.BuildID, pj.Name)
    39  	_, d, _ := gcsupload.PathsForJob(gc, &ps, "")
    40  
    41  	return gc.Bucket, d, nil
    42  }
    43  
    44  func IsGCSDestination(cfg config.Getter, pj *prowv1.ProwJob) bool {
    45  	gc, err := gcsConfig(cfg, pj)
    46  	if err != nil || gc.Bucket == "" {
    47  		return false
    48  	}
    49  	if strings.HasPrefix(gc.Bucket, "gs://") {
    50  		return true
    51  	}
    52  	// GCS is default if no other storage type is specified.
    53  	return !strings.Contains(gc.Bucket, "://")
    54  }
    55  
    56  func gcsConfig(cfg config.Getter, pj *prowv1.ProwJob) (*prowv1.GCSConfiguration, error) {
    57  	if pj.Status.BuildID == "" {
    58  		return nil, errors.New("cannot get job destination for job with no BuildID")
    59  	}
    60  
    61  	if pj.Spec.DecorationConfig != nil && pj.Spec.DecorationConfig.GCSConfiguration != nil {
    62  		return pj.Spec.DecorationConfig.GCSConfiguration, nil
    63  	}
    64  
    65  	// The decoration config is always provided for decorated jobs, but many
    66  	// jobs are not decorated, so we guess that we should use the default location
    67  	// for those jobs. This assumption is usually (but not always) correct.
    68  	// The TestGrid configurator uses the same assumption.
    69  	repo := ""
    70  	if pj.Spec.Refs != nil {
    71  		repo = pj.Spec.Refs.Org + "/" + pj.Spec.Refs.Repo
    72  	} else if len(pj.Spec.ExtraRefs) > 0 {
    73  		repo = fmt.Sprintf("%s/%s", pj.Spec.ExtraRefs[0].Org, pj.Spec.ExtraRefs[0].Repo)
    74  	}
    75  
    76  	ddc := cfg().Plank.GuessDefaultDecorationConfig(repo, pj.Spec.Cluster)
    77  	if ddc != nil && ddc.GCSConfiguration != nil {
    78  		return ddc.GCSConfiguration, nil
    79  	}
    80  	return nil, fmt.Errorf("couldn't figure out a GCS config for %q", pj.Spec.Job)
    81  }
    82  
    83  // MarshalProwJob marshals the ProwJob in the format written to GCS.
    84  func MarshalProwJob(pj *prowv1.ProwJob) ([]byte, error) {
    85  	return json.MarshalIndent(pj, "", "\t")
    86  }
    87  
    88  // MarshalFinished marshals the finished.json format written to GCS.
    89  func MarshalFinishedJSON(pj *prowv1.ProwJob) ([]byte, error) {
    90  	if !pj.Complete() {
    91  		return nil, errors.New("cannot report finished.json for incomplete job")
    92  	}
    93  	completion := pj.Status.CompletionTime.Unix()
    94  	passed := pj.Status.State == prowv1.SuccessState
    95  	f := metadata.Finished{
    96  		Timestamp: &completion,
    97  		Passed:    &passed,
    98  		Metadata:  metadata.Metadata{"uploader": "crier"},
    99  		Result:    string(pj.Status.State),
   100  	}
   101  	return json.MarshalIndent(f, "", "\t")
   102  }