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  }