github.com/jaylevin/jenkins-library@v1.230.4/cmd/abapEnvironmentAssembleConfirm.go (about) 1 package cmd 2 3 import ( 4 "encoding/json" 5 "time" 6 7 abapbuild "github.com/SAP/jenkins-library/pkg/abap/build" 8 "github.com/SAP/jenkins-library/pkg/abaputils" 9 "github.com/SAP/jenkins-library/pkg/command" 10 piperhttp "github.com/SAP/jenkins-library/pkg/http" 11 "github.com/SAP/jenkins-library/pkg/log" 12 "github.com/SAP/jenkins-library/pkg/telemetry" 13 "github.com/pkg/errors" 14 ) 15 16 func abapEnvironmentAssembleConfirm(config abapEnvironmentAssembleConfirmOptions, telemetryData *telemetry.CustomData, cpe *abapEnvironmentAssembleConfirmCommonPipelineEnvironment) { 17 // for command execution use Command 18 c := command.Command{} 19 // reroute command output to logging framework 20 c.Stdout(log.Writer()) 21 c.Stderr(log.Writer()) 22 23 var autils = abaputils.AbapUtils{ 24 Exec: &c, 25 } 26 27 client := piperhttp.Client{} 28 err := runAbapEnvironmentAssembleConfirm(&config, telemetryData, &autils, &client, cpe) 29 if err != nil { 30 log.Entry().WithError(err).Fatal("step execution failed") 31 } 32 } 33 34 func runAbapEnvironmentAssembleConfirm(config *abapEnvironmentAssembleConfirmOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client abapbuild.HTTPSendLoader, cpe *abapEnvironmentAssembleConfirmCommonPipelineEnvironment) error { 35 conn := new(abapbuild.Connector) 36 var connConfig abapbuild.ConnectorConfiguration 37 connConfig.CfAPIEndpoint = config.CfAPIEndpoint 38 connConfig.CfOrg = config.CfOrg 39 connConfig.CfSpace = config.CfSpace 40 connConfig.CfServiceInstance = config.CfServiceInstance 41 connConfig.CfServiceKeyName = config.CfServiceKeyName 42 connConfig.Host = config.Host 43 connConfig.Username = config.Username 44 connConfig.Password = config.Password 45 connConfig.AddonDescriptor = config.AddonDescriptor 46 connConfig.MaxRuntimeInMinutes = config.MaxRuntimeInMinutes 47 connConfig.CertificateNames = config.CertificateNames 48 49 err := conn.InitBuildFramework(connConfig, com, client) 50 if err != nil { 51 return err 52 } 53 var addonDescriptor abaputils.AddonDescriptor 54 err = json.Unmarshal([]byte(config.AddonDescriptor), &addonDescriptor) 55 if err != nil { 56 return err 57 } 58 delayBetweenPosts := time.Duration(3 * time.Second) 59 builds, err := startingConfirm(addonDescriptor.Repositories, *conn, delayBetweenPosts) 60 if err != nil { 61 return err 62 } 63 maxRuntimeInMinutes := time.Duration(config.MaxRuntimeInMinutes) * time.Minute 64 pollInterval := time.Duration(60 * time.Second) 65 err = polling(builds, maxRuntimeInMinutes, pollInterval) 66 if err != nil { 67 return err 68 } 69 err = checkIfFailedAndPrintLogs(builds) 70 if err != nil { 71 return err 72 } 73 return nil 74 } 75 76 func startingConfirm(repos []abaputils.Repository, conn abapbuild.Connector, delayBetweenPosts time.Duration) ([]buildWithRepository, error) { 77 var confirmedBuilds []buildWithRepository 78 for _, repo := range repos { 79 assemblyBuild := abapbuild.Build{ 80 Connector: conn, 81 } 82 buildRepo := buildWithRepository{ 83 build: assemblyBuild, 84 repo: repo, 85 } 86 if repo.InBuildScope { 87 err := buildRepo.startConfirm() 88 if err != nil { 89 return confirmedBuilds, err 90 } 91 confirmedBuilds = append(confirmedBuilds, buildRepo) 92 } else { 93 log.Entry().Infof("Packages %s was not assembled in this pipeline run, thus no need to confirm", repo.PackageName) 94 } 95 96 //as batch events in the ABAP Backend need a little time 97 time.Sleep(delayBetweenPosts) 98 } 99 return confirmedBuilds, nil 100 } 101 102 func polling(builds []buildWithRepository, maxRuntimeInMinutes time.Duration, pollInterval time.Duration) error { 103 timeout := time.After(maxRuntimeInMinutes) 104 ticker := time.Tick(pollInterval) 105 for { 106 select { 107 case <-timeout: 108 return errors.New("Timed out") 109 case <-ticker: 110 var allFinished bool = true 111 for i := range builds { 112 builds[i].build.Get() 113 if !builds[i].build.IsFinished() { 114 log.Entry().Infof("Assembly of %s is not yet finished, check again in %s", builds[i].repo.PackageName, pollInterval) 115 allFinished = false 116 } 117 } 118 if allFinished { 119 return nil 120 } 121 } 122 } 123 } 124 125 func (b *buildWithRepository) startConfirm() error { 126 if b.repo.Name == "" || b.repo.PackageName == "" { 127 return errors.New("Parameters missing. Please provide software component name, namespace and packagename") 128 } 129 valuesInput := abapbuild.Values{ 130 Values: []abapbuild.Value{ 131 { 132 ValueID: "SWC", 133 Value: b.repo.Name, 134 }, 135 }, 136 } 137 if b.repo.Namespace != "" { 138 // Steampunk Use Case, Namespace provided by AAKaaS 139 valuesInput.Values = append(valuesInput.Values, 140 abapbuild.Value{ValueID: "SSDC-delta", 141 Value: b.repo.Namespace + b.repo.PackageName}) 142 } else { 143 // Traditional SWCs, Namespace to be provided in assembly system via build script 144 valuesInput.Values = append(valuesInput.Values, 145 abapbuild.Value{ValueID: "PACKAGE_TYPE", 146 Value: b.repo.PackageType}) 147 valuesInput.Values = append(valuesInput.Values, 148 abapbuild.Value{ValueID: "PACKAGE_NAME_" + b.repo.PackageType, 149 Value: b.repo.PackageName}) 150 } 151 152 phase := "BUILD_CONFIRM" 153 log.Entry().Infof("Starting confirmation of package %s", b.repo.PackageName) 154 return b.build.Start(phase, valuesInput) 155 }