Blame cmd/osbuild-worker/jobimpl-koji-finalize.go

Packit Service 509fd4
package main
Packit Service 509fd4
Packit Service 509fd4
import (
Packit Service 509fd4
	"crypto/tls"
Packit Service 509fd4
	"fmt"
Packit Service 509fd4
	"log"
Packit Service 509fd4
	"net/http"
Packit Service 509fd4
	"net/url"
Packit Service 509fd4
	"time"
Packit Service 509fd4
Packit Service 509fd4
	"github.com/osbuild/osbuild-composer/internal/upload/koji"
Packit Service 509fd4
	"github.com/osbuild/osbuild-composer/internal/worker"
Packit Service 509fd4
)
Packit Service 509fd4
Packit Service 509fd4
type KojiFinalizeJobImpl struct {
Packit Service 509fd4
	KojiServers map[string]koji.GSSAPICredentials
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (impl *KojiFinalizeJobImpl) kojiImport(
Packit Service 509fd4
	server string,
Packit Service 509fd4
	build koji.ImageBuild,
Packit Service 509fd4
	buildRoots []koji.BuildRoot,
Packit Service 509fd4
	images []koji.Image,
Packit Service 509fd4
	directory, token string) error {
Packit Service 509fd4
	// Koji for some reason needs TLS renegotiation enabled.
Packit Service 509fd4
	// Clone the default http transport and enable renegotiation.
Packit Service 509fd4
	transport := http.DefaultTransport.(*http.Transport).Clone()
Packit Service 509fd4
	transport.TLSClientConfig = &tls.Config{
Packit Service 509fd4
		Renegotiation: tls.RenegotiateOnceAsClient,
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	serverURL, err := url.Parse(server)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	creds, exists := impl.KojiServers[serverURL.Hostname()]
Packit Service 509fd4
	if !exists {
Packit Service 509fd4
		return fmt.Errorf("Koji server has not been configured: %s", serverURL.Hostname())
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	k, err := koji.NewFromGSSAPI(server, &creds, transport)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
	defer func() {
Packit Service 509fd4
		err := k.Logout()
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			log.Printf("koji logout failed: %v", err)
Packit Service 509fd4
		}
Packit Service 509fd4
	}()
Packit Service 509fd4
Packit Service 509fd4
	_, err = k.CGImport(build, buildRoots, images, directory, token)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return fmt.Errorf("Could not import build into koji: %v", err)
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	return nil
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (impl *KojiFinalizeJobImpl) kojiFail(server string, buildID int, token string) error {
Packit Service 509fd4
	// Koji for some reason needs TLS renegotiation enabled.
Packit Service 509fd4
	// Clone the default http transport and enable renegotiation.
Packit Service 509fd4
	transport := http.DefaultTransport.(*http.Transport).Clone()
Packit Service 509fd4
	transport.TLSClientConfig = &tls.Config{
Packit Service 509fd4
		Renegotiation: tls.RenegotiateOnceAsClient,
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	serverURL, err := url.Parse(server)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	creds, exists := impl.KojiServers[serverURL.Hostname()]
Packit Service 509fd4
	if !exists {
Packit Service 509fd4
		return fmt.Errorf("Koji server has not been configured: %s", serverURL.Hostname())
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	k, err := koji.NewFromGSSAPI(server, &creds, transport)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
	defer func() {
Packit Service 509fd4
		err := k.Logout()
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			log.Printf("koji logout failed: %v", err)
Packit Service 509fd4
		}
Packit Service 509fd4
	}()
Packit Service 509fd4
Packit Service 509fd4
	return k.CGFailBuild(buildID, token)
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
func (impl *KojiFinalizeJobImpl) Run(job worker.Job) error {
Packit Service 509fd4
	var args worker.KojiFinalizeJob
Packit Service 509fd4
	err := job.Args(&args)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	initArgs, osbuildKojiResults, err := extractDynamicArgs(job)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return err
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	// Check the dependencies early. Fail the koji build if any of them failed.
Packit Service 509fd4
	if hasFailedDependency(*initArgs, osbuildKojiResults) {
Packit Service 509fd4
		err = impl.kojiFail(args.Server, int(initArgs.BuildID), initArgs.Token)
Packit Service 509fd4
Packit Service 509fd4
		// Update the status immediately and bail out.
Packit Service 509fd4
		var result worker.KojiFinalizeJobResult
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			result.KojiError = err.Error()
Packit Service 509fd4
		}
Packit Service 509fd4
		err = job.Update(&result)
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			return fmt.Errorf("Error reporting job result: %v", err)
Packit Service 509fd4
		}
Packit Service 509fd4
		return nil
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	build := koji.ImageBuild{
Packit Service 509fd4
		BuildID:   initArgs.BuildID,
Packit Service 509fd4
		TaskID:    args.TaskID,
Packit Service 509fd4
		Name:      args.Name,
Packit Service 509fd4
		Version:   args.Version,
Packit Service 509fd4
		Release:   args.Release,
Packit Service 509fd4
		StartTime: int64(args.StartTime),
Packit Service 509fd4
		EndTime:   time.Now().Unix(),
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	var buildRoots []koji.BuildRoot
Packit Service 509fd4
	var images []koji.Image
Packit Service 509fd4
	for i, buildArgs := range osbuildKojiResults {
Packit Service 509fd4
		buildRoots = append(buildRoots, koji.BuildRoot{
Packit Service 509fd4
			ID: uint64(i),
Packit Service 509fd4
			Host: koji.Host{
Packit Service 509fd4
				Os:   buildArgs.HostOS,
Packit Service 509fd4
				Arch: buildArgs.Arch,
Packit Service 509fd4
			},
Packit Service 509fd4
			ContentGenerator: koji.ContentGenerator{
Packit Service 509fd4
				Name:    "osbuild",
Packit Service 509fd4
				Version: "0", // TODO: put the correct version here
Packit Service 509fd4
			},
Packit Service 509fd4
			Container: koji.Container{
Packit Service 509fd4
				Type: "none",
Packit Service 509fd4
				Arch: buildArgs.Arch,
Packit Service 509fd4
			},
Packit Service 509fd4
			Tools: []koji.Tool{},
Packit Service 509fd4
			RPMs:  osbuildStagesToRPMs(buildArgs.OSBuildOutput.Build.Stages),
Packit Service 509fd4
		})
Packit Service 509fd4
		images = append(images, koji.Image{
Packit Service 509fd4
			BuildRootID:  uint64(i),
Packit Service 509fd4
			Filename:     args.KojiFilenames[i],
Packit Service 509fd4
			FileSize:     buildArgs.ImageSize,
Packit Service 509fd4
			Arch:         buildArgs.Arch,
Packit Service 509fd4
			ChecksumType: "md5",
Packit Service 509fd4
			MD5:          buildArgs.ImageHash,
Packit Service 509fd4
			Type:         "image",
Packit Service 509fd4
			RPMs:         osbuildStagesToRPMs(buildArgs.OSBuildOutput.Stages),
Packit Service 509fd4
			Extra: koji.ImageExtra{
Packit Service 509fd4
				Info: koji.ImageExtraInfo{
Packit Service 509fd4
					Arch: buildArgs.Arch,
Packit Service 509fd4
				},
Packit Service 509fd4
			},
Packit Service 509fd4
		})
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	var result worker.KojiFinalizeJobResult
Packit Service 509fd4
	err = impl.kojiImport(args.Server, build, buildRoots, images, args.KojiDirectory, initArgs.Token)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		result.KojiError = err.Error()
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	err = job.Update(&result)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return fmt.Errorf("Error reporting job result: %v", err)
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	return nil
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Extracts dynamic args of the koji-finalize job. Returns an error if they
Packit Service 509fd4
// cannot be unmarshalled.
Packit Service 509fd4
func extractDynamicArgs(job worker.Job) (*worker.KojiInitJobResult, []worker.OSBuildKojiJobResult, error) {
Packit Service 509fd4
	var kojiInitResult worker.KojiInitJobResult
Packit Service 509fd4
	err := job.DynamicArgs(0, &kojiInitResult)
Packit Service 509fd4
	if err != nil {
Packit Service 509fd4
		return nil, nil, err
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	osbuildKojiResults := make([]worker.OSBuildKojiJobResult, job.NDynamicArgs()-1)
Packit Service 509fd4
Packit Service 509fd4
	for i := 1; i < job.NDynamicArgs(); i++ {
Packit Service 509fd4
		err = job.DynamicArgs(i, &osbuildKojiResults[i-1])
Packit Service 509fd4
		if err != nil {
Packit Service 509fd4
			return nil, nil, err
Packit Service 509fd4
		}
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	return &kojiInitResult, osbuildKojiResults, nil
Packit Service 509fd4
}
Packit Service 509fd4
Packit Service 509fd4
// Returns true if any of koji-finalize dependencies failed.
Packit Service 509fd4
func hasFailedDependency(kojiInitResult worker.KojiInitJobResult, osbuildKojiResults []worker.OSBuildKojiJobResult) bool {
Packit Service 509fd4
	if kojiInitResult.KojiError != "" {
Packit Service 509fd4
		return true
Packit Service 509fd4
	}
Packit Service 509fd4
Packit Service 509fd4
	for _, r := range osbuildKojiResults {
Packit Service 509fd4
		if !r.OSBuildOutput.Success || r.KojiError != "" {
Packit Service 509fd4
			return true
Packit Service 509fd4
		}
Packit Service 509fd4
	}
Packit Service 509fd4
	return false
Packit Service 509fd4
}