debian-forge-composer/cmd/osbuild-worker/jobimpl-osbuild-koji.go
Tom Gundersen bf86e8ad79 workerapi: serialize koji errors as strings
Serializing an interface does not work, let us simply use the string
representation and treat the empty string as no error. This is
compatible with the current API in the success case, and fixes the
error case, which is currently broken.

Also extend the test matrix for the kojiapi to ensure that all the
different kinds of errors can be serialized correctly and leads to
the correct status being returned.

Fixes #1079 and #1080.
2020-11-13 09:39:55 +01:00

111 lines
2.6 KiB
Go

package main
import (
"crypto/tls"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"path"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/upload/koji"
"github.com/osbuild/osbuild-composer/internal/worker"
)
type OSBuildKojiJobImpl struct {
Store string
KojiServers map[string]koji.GSSAPICredentials
}
func (impl *OSBuildKojiJobImpl) kojiUpload(file *os.File, server, directory, filename string) (string, uint64, error) {
// Koji for some reason needs TLS renegotiation enabled.
// Clone the default http transport and enable renegotiation.
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.TLSClientConfig = &tls.Config{
Renegotiation: tls.RenegotiateOnceAsClient,
}
serverURL, err := url.Parse(server)
if err != nil {
return "", 0, err
}
creds, exists := impl.KojiServers[serverURL.Hostname()]
if !exists {
return "", 0, fmt.Errorf("Koji server has not been configured: %s", serverURL.Hostname())
}
k, err := koji.NewFromGSSAPI(server, &creds, transport)
if err != nil {
return "", 0, err
}
defer func() {
err := k.Logout()
if err != nil {
log.Printf("koji logout failed: %v", err)
}
}()
return k.Upload(file, directory, filename)
}
func (impl *OSBuildKojiJobImpl) Run(job worker.Job) error {
outputDirectory, err := ioutil.TempDir("/var/tmp", "osbuild-worker-*")
if err != nil {
return fmt.Errorf("error creating temporary output directory: %v", err)
}
defer func() {
err := os.RemoveAll(outputDirectory)
if err != nil {
log.Printf("Error removing temporary output directory (%s): %v", outputDirectory, err)
}
}()
var args worker.OSBuildKojiJob
err = job.Args(&args)
if err != nil {
return err
}
var initArgs worker.KojiInitJobResult
err = job.DynamicArgs(0, &initArgs)
if err != nil {
return err
}
var result worker.OSBuildKojiJobResult
result.Arch = common.CurrentArch()
result.HostOS, err = distro.GetRedHatRelease()
if err != nil {
return err
}
if initArgs.KojiError == "" {
result.OSBuildOutput, err = RunOSBuild(args.Manifest, impl.Store, outputDirectory, os.Stderr)
if err != nil {
return err
}
if result.OSBuildOutput.Success {
f, err := os.Open(path.Join(outputDirectory, args.ImageName))
if err != nil {
return err
}
result.ImageHash, result.ImageSize, err = impl.kojiUpload(f, args.KojiServer, args.KojiDirectory, args.KojiFilename)
if err != nil {
result.KojiError = err.Error()
}
}
}
err = job.Update(&result)
if err != nil {
return fmt.Errorf("Error reporting job result: %v", err)
}
return nil
}