worker: Define new jobs to handle copying and resharing of images
The copy job copies from one region to another. It does not preserve the sharing on the ami and it's snapshot, that needs to be queued separately.
This commit is contained in:
parent
5e9ecd3ae4
commit
099b34b301
5 changed files with 405 additions and 42 deletions
144
cmd/osbuild-worker/jobimpl-awsec2.go
Normal file
144
cmd/osbuild-worker/jobimpl-awsec2.go
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/osbuild/osbuild-composer/internal/cloud/awscloud"
|
||||
"github.com/osbuild/osbuild-composer/internal/worker"
|
||||
"github.com/osbuild/osbuild-composer/internal/worker/clienterrors"
|
||||
)
|
||||
|
||||
func getAWS(awsCreds, region string) (*awscloud.AWS, error) {
|
||||
if awsCreds != "" {
|
||||
return awscloud.NewFromFile(awsCreds, region)
|
||||
}
|
||||
return awscloud.NewDefault(region)
|
||||
}
|
||||
|
||||
type AWSEC2CopyJobImpl struct {
|
||||
AWSCreds string
|
||||
}
|
||||
|
||||
func (impl *AWSEC2CopyJobImpl) Run(job worker.Job) error {
|
||||
logWithId := logrus.WithField("jobId", job.Id())
|
||||
result := worker.AWSEC2CopyJobResult{}
|
||||
|
||||
defer func() {
|
||||
err := job.Update(&result)
|
||||
if err != nil {
|
||||
logWithId.Errorf("Error reporting job result: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
var args worker.AWSEC2CopyJob
|
||||
err := job.Args(&args)
|
||||
if err != nil {
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorParsingJobArgs, fmt.Sprintf("Error parsing arguments: %v", err), nil)
|
||||
return err
|
||||
}
|
||||
|
||||
aws, err := getAWS(impl.AWSCreds, args.TargetRegion)
|
||||
if err != nil {
|
||||
logWithId.Errorf("Error creating aws client: %v", err)
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, "Invalid worker config", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
ami, err := aws.CopyImage(args.TargetName, args.Ami, args.SourceRegion)
|
||||
if err != nil {
|
||||
logWithId.Errorf("Error copying ami: %v", err)
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Error copying ami %s", args.Ami), nil)
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case "InvalidRegion":
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Invalid source region '%s'", args.SourceRegion), nil)
|
||||
case "InvalidAMIID.Malformed":
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Malformed source ami id '%s'", args.Ami), nil)
|
||||
case "InvalidAMIID.NotFound":
|
||||
fallthrough // CopyImage returns InvalidRequest instead of InvalidAMIID.NotFound
|
||||
case "InvalidRequest":
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Source ami '%s' not found", args.Ami), nil)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
result.Ami = ami
|
||||
result.Region = args.TargetRegion
|
||||
return nil
|
||||
}
|
||||
|
||||
type AWSEC2ShareJobImpl struct {
|
||||
AWSCreds string
|
||||
}
|
||||
|
||||
func (impl *AWSEC2ShareJobImpl) Run(job worker.Job) error {
|
||||
logWithId := logrus.WithField("jobId", job.Id())
|
||||
result := worker.AWSEC2ShareJobResult{}
|
||||
|
||||
defer func() {
|
||||
err := job.Update(&result)
|
||||
if err != nil {
|
||||
logWithId.Errorf("Error reporting job result: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
var args worker.AWSEC2ShareJob
|
||||
err := job.Args(&args)
|
||||
if err != nil {
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorParsingJobArgs, fmt.Sprintf("Error parsing arguments: %v", err), nil)
|
||||
return err
|
||||
}
|
||||
|
||||
if args.Ami == "" || args.Region == "" {
|
||||
if job.NDynamicArgs() != 1 {
|
||||
logWithId.Error("No arguments given and dynamic args empty")
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorNoDynamicArgs, "An ec2 share job should have args or depend on an ec2 copy job", nil)
|
||||
return nil
|
||||
}
|
||||
var cjResult worker.AWSEC2CopyJobResult
|
||||
err = job.DynamicArgs(0, &cjResult)
|
||||
if err != nil {
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorParsingDynamicArgs, "Error parsing dynamic args as ec2 copy job", nil)
|
||||
return err
|
||||
}
|
||||
if cjResult.JobError != nil {
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorJobDependency, "AWSEC2CopyJob dependency failed", nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
args.Ami = cjResult.Ami
|
||||
args.Region = cjResult.Region
|
||||
}
|
||||
|
||||
aws, err := getAWS(impl.AWSCreds, args.Region)
|
||||
if err != nil {
|
||||
logWithId.Errorf("Error creating aws client: %v", err)
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, "Invalid worker config", nil)
|
||||
return err
|
||||
}
|
||||
|
||||
err = aws.ShareImage(args.Ami, args.ShareWithAccounts)
|
||||
if err != nil {
|
||||
logWithId.Errorf("Error sharing image: %v", err)
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Error sharing image with target %v", args.ShareWithAccounts), nil)
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
switch aerr.Code() {
|
||||
case "InvalidAMIID.Malformed":
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Malformed ami id '%s'", args.Ami), nil)
|
||||
case "InvalidAMIID.NotFound":
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Ami '%s' not found in region '%s'", args.Ami, args.Region), nil)
|
||||
case "InvalidAMIAttributeItemValue":
|
||||
result.JobError = clienterrors.WorkerClientError(clienterrors.ErrorSharingTarget, fmt.Sprintf("Invalid user id to share ami with: %v", args.ShareWithAccounts), nil)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
result.Ami = args.Ami
|
||||
result.Region = args.Region
|
||||
return nil
|
||||
}
|
||||
|
|
@ -464,6 +464,12 @@ func main() {
|
|||
worker.JobTypeContainerResolve: &ContainerResolveJobImpl{
|
||||
AuthFilePath: containersAuthFilePath,
|
||||
},
|
||||
worker.JobTypeAWSEC2Copy: &AWSEC2CopyJobImpl{
|
||||
AWSCreds: awsCredentials,
|
||||
},
|
||||
worker.JobTypeAWSEC2Share: &AWSEC2ShareJobImpl{
|
||||
AWSCreds: awsCredentials,
|
||||
},
|
||||
}
|
||||
|
||||
acceptedJobTypes := []string{}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue