github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/spyglass/lenses/metadata/lens.go (about)

     1  /*
     2  Copyright 2018 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 metadata provides a metadata viewer for Spyglass
    18  package metadata
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/json"
    23  	"time"
    24  
    25  	"fmt"
    26  	"html/template"
    27  	"path/filepath"
    28  
    29  	"github.com/sirupsen/logrus"
    30  	"k8s.io/test-infra/prow/deck/jobs"
    31  	"k8s.io/test-infra/prow/spyglass/lenses"
    32  )
    33  
    34  const (
    35  	name     = "metadata"
    36  	title    = "Metadata"
    37  	priority = 0
    38  )
    39  
    40  // Lens is the implementation of a metadata-rendering Spyglass lens.
    41  type Lens struct{}
    42  
    43  func init() {
    44  	lenses.RegisterLens(Lens{})
    45  }
    46  
    47  // Title returns the title.
    48  func (lens Lens) Title() string {
    49  	return title
    50  }
    51  
    52  // Name returns the name.
    53  func (lens Lens) Name() string {
    54  	return name
    55  }
    56  
    57  // Priority returns the priority.
    58  func (lens Lens) Priority() int {
    59  	return priority
    60  }
    61  
    62  // Header renders the <head> from template.html.
    63  func (lens Lens) Header(artifacts []lenses.Artifact, resourceDir string) string {
    64  	t, err := template.ParseFiles(filepath.Join(resourceDir, "template.html"))
    65  	if err != nil {
    66  		return fmt.Sprintf("<!-- FAILED LOADING HEADER: %v -->", err)
    67  	}
    68  	var buf bytes.Buffer
    69  	if err := t.ExecuteTemplate(&buf, "header", nil); err != nil {
    70  		return fmt.Sprintf("<!-- FAILED EXECUTING HEADER TEMPLATE: %v -->", err)
    71  	}
    72  	return buf.String()
    73  }
    74  
    75  // Callback does nothing.
    76  func (lens Lens) Callback(artifacts []lenses.Artifact, resourceDir string, data string) string {
    77  	return ""
    78  }
    79  
    80  // Body creates a view for prow job metadata.
    81  func (lens Lens) Body(artifacts []lenses.Artifact, resourceDir string, data string) string {
    82  	var buf bytes.Buffer
    83  	type MetadataViewData struct {
    84  		Status       string
    85  		StartTime    time.Time
    86  		FinishedTime time.Time
    87  		Elapsed      time.Duration
    88  		Metadata     map[string]string
    89  		MetadataLen  int
    90  	}
    91  	metadataViewData := MetadataViewData{Status: "Pending"}
    92  	started := jobs.Started{}
    93  	finished := jobs.Finished{}
    94  	for _, a := range artifacts {
    95  		read, err := a.ReadAll()
    96  		if err != nil {
    97  			logrus.WithError(err).Error("Failed reading from artifact.")
    98  		}
    99  		if a.JobPath() == "started.json" {
   100  			if err = json.Unmarshal(read, &started); err != nil {
   101  				logrus.WithError(err).Error("Error unmarshaling started.json")
   102  			}
   103  			metadataViewData.StartTime = time.Unix(started.Timestamp, 0)
   104  		} else if a.JobPath() == "finished.json" {
   105  			if err = json.Unmarshal(read, &finished); err != nil {
   106  				logrus.WithError(err).Error("Error unmarshaling finished.json")
   107  			}
   108  			metadataViewData.FinishedTime = time.Unix(finished.Timestamp, 0)
   109  			metadataViewData.Status = finished.Result
   110  		}
   111  	}
   112  
   113  	if !metadataViewData.StartTime.IsZero() {
   114  		if metadataViewData.FinishedTime.IsZero() {
   115  			metadataViewData.Elapsed = time.Now().Sub(metadataViewData.StartTime)
   116  		} else {
   117  			metadataViewData.Elapsed =
   118  				metadataViewData.FinishedTime.Sub(metadataViewData.StartTime)
   119  		}
   120  	}
   121  
   122  	metadataViewData.Metadata = map[string]string{
   123  		"Node":         started.Node,
   124  		"Repo":         finished.Metadata.Repo,
   125  		"Repo Commit":  finished.Metadata.RepoCommit,
   126  		"Infra Commit": finished.Metadata.InfraCommit,
   127  		"Pod":          finished.Metadata.Pod,
   128  	}
   129  	for pkg, version := range finished.Metadata.Repos {
   130  		metadataViewData.Metadata[pkg] = version
   131  	}
   132  	for _, v := range metadataViewData.Metadata {
   133  		if v != "" {
   134  			metadataViewData.MetadataLen++
   135  		}
   136  	}
   137  
   138  	metadataTemplate, err := template.ParseFiles(filepath.Join(resourceDir, "template.html"))
   139  	if err != nil {
   140  		return fmt.Sprintf("Failed to load template: %v", err)
   141  	}
   142  
   143  	if err := metadataTemplate.ExecuteTemplate(&buf, "body", metadataViewData); err != nil {
   144  		logrus.WithError(err).Error("Error executing template.")
   145  	}
   146  	return buf.String()
   147  }