1package commands 2 3import ( 4 "fmt" 5 "os" 6 "strconv" 7 "time" 8 9 "github.com/concourse/concourse/atc" 10 "github.com/concourse/concourse/fly/commands/internal/flaghelpers" 11 "github.com/concourse/concourse/fly/rc" 12 "github.com/concourse/concourse/fly/ui" 13 "github.com/fatih/color" 14) 15 16type CheckResourceCommand struct { 17 Resource flaghelpers.ResourceFlag `short:"r" long:"resource" required:"true" value-name:"PIPELINE/RESOURCE" description:"Name of a resource to check version for"` 18 Version *atc.Version `short:"f" long:"from" value-name:"VERSION" description:"Version of the resource to check from, e.g. ref:abcd or path:thing-1.2.3.tgz"` 19 Async bool `short:"a" long:"async" value-name:"ASYNC" description:"Return the check without waiting for its result"` 20 Shallow bool `long:"shallow" value-name:"SHALLOW" description:"Check the resource itself only"` 21} 22 23func (command *CheckResourceCommand) Execute(args []string) error { 24 target, err := rc.LoadTarget(Fly.Target, Fly.Verbose) 25 if err != nil { 26 return err 27 } 28 29 err = target.Validate() 30 if err != nil { 31 return err 32 } 33 34 var version atc.Version 35 if command.Version != nil { 36 version = *command.Version 37 } 38 39 if !command.Shallow { 40 err = command.checkParent(target) 41 if err != nil { 42 return err 43 } 44 } 45 46 check, found, err := target.Team().CheckResource(command.Resource.PipelineName, command.Resource.ResourceName, version) 47 if err != nil { 48 return err 49 } 50 51 if !found { 52 return fmt.Errorf("pipeline '%s' or resource '%s' not found\n", command.Resource.PipelineName, command.Resource.ResourceName) 53 } 54 55 var checkID = strconv.Itoa(check.ID) 56 57 if !command.Async { 58 for check.Status == "started" { 59 time.Sleep(time.Second) 60 61 check, found, err = target.Client().Check(checkID) 62 if err != nil { 63 return err 64 } 65 66 if !found { 67 return fmt.Errorf("check '%s' not found\n", checkID) 68 } 69 } 70 } 71 72 table := ui.Table{ 73 Headers: ui.TableRow{ 74 {Contents: "id", Color: color.New(color.Bold)}, 75 {Contents: "name", Color: color.New(color.Bold)}, 76 {Contents: "status", Color: color.New(color.Bold)}, 77 {Contents: "check_error", Color: color.New(color.Bold)}, 78 }, 79 } 80 81 table.Data = append(table.Data, []ui.TableCell{ 82 {Contents: checkID}, 83 {Contents: command.Resource.ResourceName}, 84 {Contents: check.Status}, 85 {Contents: check.CheckError}, 86 }) 87 88 if err = table.Render(os.Stdout, Fly.PrintTableHeaders); err != nil { 89 return err 90 } 91 92 if check.Status == "errored" { 93 os.Exit(1) 94 } 95 96 return nil 97} 98 99func (command *CheckResourceCommand) checkParent(target rc.Target) error { 100 resource, found, err := target.Team().Resource(command.Resource.PipelineName, command.Resource.ResourceName) 101 if err != nil { 102 return err 103 } 104 105 if !found { 106 return fmt.Errorf("resource '%s' not found\n", command.Resource.ResourceName) 107 } 108 109 resourceTypes, found, err := target.Team().VersionedResourceTypes(command.Resource.PipelineName) 110 if err != nil { 111 return err 112 } 113 114 if !found { 115 return fmt.Errorf("pipeline '%s' not found\n", command.Resource.PipelineName) 116 } 117 118 parentType, found := command.findParent(resource, resourceTypes) 119 if !found { 120 return nil 121 } 122 123 cmd := &CheckResourceTypeCommand{ 124 ResourceType: flaghelpers.ResourceFlag{ 125 ResourceName: parentType.Name, 126 PipelineName: command.Resource.PipelineName, 127 }, 128 } 129 130 return cmd.Execute(nil) 131} 132 133func (command *CheckResourceCommand) findParent(resource atc.Resource, resourceTypes atc.VersionedResourceTypes) (atc.VersionedResourceType, bool) { 134 for _, t := range resourceTypes { 135 if t.Name != resource.Name && t.Name == resource.Type { 136 return t, true 137 } 138 } 139 return atc.VersionedResourceType{}, false 140} 141