mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
6151f36d88
* Remove --backend-type * Delete CTS in isChangeDevelopment and change Dockerimage of CM-Client * fix groovy unit tests * another fix of groovy unit tests * try to fix import of fork for Jenkins-Testing * add workflow to create Go Binary for Jenkins-Server * Change RepoOwner to test in Fork * remove previous changes * adjust docker image for TransportRequestCreate and Release * Remove CTS from Documentation Co-authored-by: Thorsten Duda <thorsten.duda@sap.com>
137 lines
3.8 KiB
Go
137 lines
3.8 KiB
Go
package solman
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/SAP/jenkins-library/pkg/config/validation"
|
|
"github.com/SAP/jenkins-library/pkg/log"
|
|
"github.com/pkg/errors"
|
|
"strings"
|
|
)
|
|
|
|
// FileSystem interface collecting everything which is file system
|
|
// related and needed in the context of a SOLMAN upload.
|
|
type FileSystem interface {
|
|
FileExists(path string) (bool, error)
|
|
}
|
|
|
|
// UploadAction Collects all the properties we need for the deployment
|
|
type UploadAction struct {
|
|
Connection Connection
|
|
ChangeDocumentID string
|
|
TransportRequestID string
|
|
ApplicationID string
|
|
File string
|
|
CMOpts []string
|
|
}
|
|
|
|
// Action collects everything which is needed to perform a SOLMAN upload
|
|
type Action interface {
|
|
WithConnection(Connection)
|
|
WithChangeDocumentID(string)
|
|
WithTransportRequestID(string)
|
|
WithApplicationID(string)
|
|
WithFile(string)
|
|
WithCMOpts([]string)
|
|
Perform(fs FileSystem, command Exec) error
|
|
}
|
|
|
|
// WithConnection specifies all the connection details which
|
|
// are required in order to connect to SOLMAN
|
|
func (a *UploadAction) WithConnection(c Connection) {
|
|
a.Connection = c
|
|
}
|
|
|
|
// WithChangeDocumentID specifies the change document which
|
|
// receives the executable.
|
|
func (a *UploadAction) WithChangeDocumentID(id string) {
|
|
a.ChangeDocumentID = id
|
|
}
|
|
|
|
// WithTransportRequestID specifies the transport request which
|
|
// receives the executable.
|
|
func (a *UploadAction) WithTransportRequestID(id string) {
|
|
a.TransportRequestID = id
|
|
}
|
|
|
|
// WithApplicationID specifies the application ID.
|
|
func (a *UploadAction) WithApplicationID(id string) {
|
|
a.ApplicationID = id
|
|
}
|
|
|
|
// WithFile specifies the executable which should be uploaded into
|
|
// a transport on SOLMAN
|
|
func (a *UploadAction) WithFile(f string) {
|
|
a.File = f
|
|
}
|
|
|
|
// WithCMOpts sets additional options for calling the
|
|
// cm client tool. E.g. -D options. Useful for troubleshooting
|
|
func (a *UploadAction) WithCMOpts(opts []string) {
|
|
a.CMOpts = opts
|
|
}
|
|
|
|
// Perform performs the SOLMAN upload
|
|
func (a *UploadAction) Perform(fs FileSystem, command Exec) error {
|
|
|
|
log.Entry().Infof("Deploying artifact '%s' to '%s'.",
|
|
a.File, a.Connection.Endpoint)
|
|
|
|
missingParameters, err := validation.FindEmptyStringsInConfigStruct(*a)
|
|
|
|
if err == nil {
|
|
notInitialized := len(missingParameters) != 0
|
|
if notInitialized {
|
|
err = fmt.Errorf("the following parameters are not available '%s'", missingParameters)
|
|
}
|
|
}
|
|
|
|
if err == nil {
|
|
var exists bool
|
|
exists, err = fs.FileExists(a.File)
|
|
|
|
if err == nil && !exists {
|
|
err = fmt.Errorf("file '%s' does not exist", a.File)
|
|
}
|
|
}
|
|
|
|
if err == nil {
|
|
if len(a.CMOpts) > 0 {
|
|
command.SetEnv([]string{fmt.Sprintf("CMCLIENT_OPTS=%s", strings.Join(a.CMOpts, " "))})
|
|
}
|
|
|
|
err = command.RunExecutable("cmclient",
|
|
"--endpoint", a.Connection.Endpoint,
|
|
"--user", a.Connection.User,
|
|
"--password", a.Connection.Password,
|
|
"upload-file-to-transport",
|
|
"-cID", a.ChangeDocumentID,
|
|
"-tID", a.TransportRequestID,
|
|
a.ApplicationID, a.File)
|
|
|
|
exitCode := command.GetExitCode()
|
|
|
|
if exitCode != 0 {
|
|
message := fmt.Sprintf("upload command returned with exit code '%d'", exitCode)
|
|
if err != nil {
|
|
// Using the wrapping here is to some extend an abuse, since it is not really
|
|
// error chaining (the other error is not necessaryly a "predecessor" of this one).
|
|
// But it is a pragmatic approach for not loosing information for trouble shooting. There
|
|
// is no possibility to have something like suppressed errors.
|
|
err = errors.Wrap(err, message)
|
|
} else {
|
|
err = errors.New(message)
|
|
}
|
|
}
|
|
}
|
|
|
|
if err == nil {
|
|
log.Entry().Infof("Deployment succeeded, artifact: '%s', endpoint: '%s'",
|
|
a.File, a.Connection.Endpoint)
|
|
} else {
|
|
log.Entry().WithError(err).Warnf("Deployment failed, artifact: '%s', endpoint: '%s'",
|
|
a.File, a.Connection.Endpoint)
|
|
}
|
|
|
|
return errors.Wrapf(err, "cannot upload artifact '%s'", a.File)
|
|
}
|