This moves some of the code from the PostCompose function in handler.go into methods on the OpenAPI ComposeRequest and ImageRequest structs. In compose.go I have added several methods. GetBlueprintWithCustomizations takes the ComposeRequest customizations and builds a Blueprint struct. GetPayloadRepositories returns the custom payload repos. GetSubscription returns the ImageOptions setup with optional subscription information from the request. In imagerequest.go I have added GetTarget which takes the upload options and returns a Target. This moves the giant switch statement, which may also benefit from further simplification at some point. GetOSTreeOptions returns the OSTree ImageOptions if there are ostree settings in the ImageRequest. GetImageOptions returns the distro.ImageOptions with the size set. This commit only moves the code, making PostCompose easier to read. All tests still pass. cloudapi: Move the size handling to a method on ImageRequest
318 lines
9.1 KiB
Go
318 lines
9.1 KiB
Go
package v2
|
|
|
|
// ComposeRequest methods to make it easier to use and test
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/osbuild/images/pkg/subscription"
|
|
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
|
)
|
|
|
|
// GetBlueprintWithCustomizations returns a new Blueprint with all of the
|
|
// customizations set from the ComposeRequest
|
|
func (request *ComposeRequest) GetBlueprintWithCustomizations() (blueprint.Blueprint, error) {
|
|
var bp = blueprint.Blueprint{Name: "empty blueprint"}
|
|
err := bp.Initialize()
|
|
if err != nil {
|
|
return bp, HTTPErrorWithInternal(ErrorFailedToInitializeBlueprint, err)
|
|
}
|
|
|
|
if request.Customizations == nil {
|
|
return bp, nil
|
|
}
|
|
|
|
// Set the blueprint customisation to take care of the user
|
|
if request.Customizations.Users != nil {
|
|
var userCustomizations []blueprint.UserCustomization
|
|
for _, user := range *request.Customizations.Users {
|
|
var groups []string
|
|
if user.Groups != nil {
|
|
groups = *user.Groups
|
|
} else {
|
|
groups = nil
|
|
}
|
|
userCustomizations = append(userCustomizations,
|
|
blueprint.UserCustomization{
|
|
Name: user.Name,
|
|
Key: user.Key,
|
|
Groups: groups,
|
|
},
|
|
)
|
|
}
|
|
if bp.Customizations == nil {
|
|
bp.Customizations = &blueprint.Customizations{
|
|
User: userCustomizations,
|
|
}
|
|
} else {
|
|
bp.Customizations.User = userCustomizations
|
|
}
|
|
}
|
|
|
|
if request.Customizations.Packages != nil {
|
|
for _, p := range *request.Customizations.Packages {
|
|
bp.Packages = append(bp.Packages, blueprint.Package{
|
|
Name: p,
|
|
})
|
|
}
|
|
}
|
|
|
|
if request.Customizations.Containers != nil {
|
|
for _, c := range *request.Customizations.Containers {
|
|
bc := blueprint.Container{
|
|
Source: c.Source,
|
|
TLSVerify: c.TlsVerify,
|
|
}
|
|
if c.Name != nil {
|
|
bc.Name = *c.Name
|
|
}
|
|
bp.Containers = append(bp.Containers, bc)
|
|
}
|
|
}
|
|
|
|
if request.Customizations.Directories != nil {
|
|
var dirCustomizations []blueprint.DirectoryCustomization
|
|
for _, d := range *request.Customizations.Directories {
|
|
dirCustomization := blueprint.DirectoryCustomization{
|
|
Path: d.Path,
|
|
}
|
|
if d.Mode != nil {
|
|
dirCustomization.Mode = *d.Mode
|
|
}
|
|
if d.User != nil {
|
|
dirCustomization.User = *d.User
|
|
if uid, ok := dirCustomization.User.(float64); ok {
|
|
// check if uid can be converted to int64
|
|
if uid != float64(int64(uid)) {
|
|
return bp, fmt.Errorf("invalid user %f: must be an integer", uid)
|
|
}
|
|
dirCustomization.User = int64(uid)
|
|
}
|
|
}
|
|
if d.Group != nil {
|
|
dirCustomization.Group = *d.Group
|
|
if gid, ok := dirCustomization.Group.(float64); ok {
|
|
// check if gid can be converted to int64
|
|
if gid != float64(int64(gid)) {
|
|
return bp, fmt.Errorf("invalid group %f: must be an integer", gid)
|
|
}
|
|
dirCustomization.Group = int64(gid)
|
|
}
|
|
}
|
|
if d.EnsureParents != nil {
|
|
dirCustomization.EnsureParents = *d.EnsureParents
|
|
}
|
|
dirCustomizations = append(dirCustomizations, dirCustomization)
|
|
}
|
|
|
|
// Validate the directory customizations, because the Cloud API does not use the custom unmarshaller
|
|
_, err := blueprint.DirectoryCustomizationsToFsNodeDirectories(dirCustomizations)
|
|
if err != nil {
|
|
return bp, HTTPErrorWithInternal(ErrorInvalidCustomization, err)
|
|
}
|
|
|
|
if bp.Customizations == nil {
|
|
bp.Customizations = &blueprint.Customizations{
|
|
Directories: dirCustomizations,
|
|
}
|
|
} else {
|
|
bp.Customizations.Directories = dirCustomizations
|
|
}
|
|
}
|
|
|
|
if request.Customizations.Files != nil {
|
|
var fileCustomizations []blueprint.FileCustomization
|
|
for _, f := range *request.Customizations.Files {
|
|
fileCustomization := blueprint.FileCustomization{
|
|
Path: f.Path,
|
|
}
|
|
if f.Data != nil {
|
|
fileCustomization.Data = *f.Data
|
|
}
|
|
if f.Mode != nil {
|
|
fileCustomization.Mode = *f.Mode
|
|
}
|
|
if f.User != nil {
|
|
fileCustomization.User = *f.User
|
|
if uid, ok := fileCustomization.User.(float64); ok {
|
|
// check if uid can be converted to int64
|
|
if uid != float64(int64(uid)) {
|
|
return bp, fmt.Errorf("invalid user %f: must be an integer", uid)
|
|
}
|
|
fileCustomization.User = int64(uid)
|
|
}
|
|
}
|
|
if f.Group != nil {
|
|
fileCustomization.Group = *f.Group
|
|
if gid, ok := fileCustomization.Group.(float64); ok {
|
|
// check if gid can be converted to int64
|
|
if gid != float64(int64(gid)) {
|
|
return bp, fmt.Errorf("invalid group %f: must be an integer", gid)
|
|
}
|
|
fileCustomization.Group = int64(gid)
|
|
}
|
|
}
|
|
fileCustomizations = append(fileCustomizations, fileCustomization)
|
|
}
|
|
|
|
// Validate the file customizations, because the Cloud API does not use the custom unmarshaller
|
|
_, err := blueprint.FileCustomizationsToFsNodeFiles(fileCustomizations)
|
|
if err != nil {
|
|
return bp, HTTPErrorWithInternal(ErrorInvalidCustomization, err)
|
|
}
|
|
|
|
if bp.Customizations == nil {
|
|
bp.Customizations = &blueprint.Customizations{
|
|
Files: fileCustomizations,
|
|
}
|
|
} else {
|
|
bp.Customizations.Files = fileCustomizations
|
|
}
|
|
}
|
|
|
|
if request.Customizations.Filesystem != nil {
|
|
var fsCustomizations []blueprint.FilesystemCustomization
|
|
for _, f := range *request.Customizations.Filesystem {
|
|
|
|
fsCustomizations = append(fsCustomizations,
|
|
blueprint.FilesystemCustomization{
|
|
Mountpoint: f.Mountpoint,
|
|
MinSize: f.MinSize,
|
|
},
|
|
)
|
|
}
|
|
if bp.Customizations == nil {
|
|
bp.Customizations = &blueprint.Customizations{
|
|
Filesystem: fsCustomizations,
|
|
}
|
|
} else {
|
|
bp.Customizations.Filesystem = fsCustomizations
|
|
}
|
|
}
|
|
|
|
if request.Customizations.Services != nil {
|
|
servicesCustomization := &blueprint.ServicesCustomization{}
|
|
if request.Customizations.Services.Enabled != nil {
|
|
servicesCustomization.Enabled = make([]string, len(*request.Customizations.Services.Enabled))
|
|
copy(servicesCustomization.Enabled, *request.Customizations.Services.Enabled)
|
|
}
|
|
if request.Customizations.Services.Disabled != nil {
|
|
servicesCustomization.Disabled = make([]string, len(*request.Customizations.Services.Disabled))
|
|
copy(servicesCustomization.Disabled, *request.Customizations.Services.Disabled)
|
|
}
|
|
if bp.Customizations == nil {
|
|
bp.Customizations = &blueprint.Customizations{
|
|
Services: servicesCustomization,
|
|
}
|
|
} else {
|
|
bp.Customizations.Services = servicesCustomization
|
|
}
|
|
}
|
|
|
|
if request.Customizations.Openscap != nil {
|
|
openSCAPCustomization := &blueprint.OpenSCAPCustomization{
|
|
ProfileID: request.Customizations.Openscap.ProfileId,
|
|
}
|
|
if bp.Customizations == nil {
|
|
bp.Customizations = &blueprint.Customizations{
|
|
OpenSCAP: openSCAPCustomization,
|
|
}
|
|
} else {
|
|
bp.Customizations.OpenSCAP = openSCAPCustomization
|
|
}
|
|
}
|
|
|
|
if request.Customizations.CustomRepositories != nil {
|
|
repoCustomizations := []blueprint.RepositoryCustomization{}
|
|
for _, repo := range *request.Customizations.CustomRepositories {
|
|
repoCustomization := blueprint.RepositoryCustomization{
|
|
Id: repo.Id,
|
|
}
|
|
|
|
if repo.Name != nil {
|
|
repoCustomization.Name = *repo.Name
|
|
}
|
|
|
|
if repo.Filename != nil {
|
|
repoCustomization.Filename = *repo.Filename
|
|
}
|
|
|
|
if repo.Baseurl != nil && len(*repo.Baseurl) > 0 {
|
|
repoCustomization.BaseURLs = *repo.Baseurl
|
|
}
|
|
|
|
if repo.Gpgkey != nil && len(*repo.Gpgkey) > 0 {
|
|
repoCustomization.GPGKeys = *repo.Gpgkey
|
|
}
|
|
|
|
if repo.CheckGpg != nil {
|
|
repoCustomization.GPGCheck = repo.CheckGpg
|
|
}
|
|
|
|
if repo.CheckRepoGpg != nil {
|
|
repoCustomization.RepoGPGCheck = repo.CheckRepoGpg
|
|
}
|
|
|
|
if repo.Enabled != nil {
|
|
repoCustomization.Enabled = repo.Enabled
|
|
}
|
|
|
|
if repo.Metalink != nil {
|
|
repoCustomization.Metalink = *repo.Metalink
|
|
}
|
|
|
|
if repo.Mirrorlist != nil {
|
|
repoCustomization.Mirrorlist = *repo.Mirrorlist
|
|
}
|
|
|
|
if repo.SslVerify != nil {
|
|
repoCustomization.SSLVerify = repo.SslVerify
|
|
}
|
|
|
|
if repo.Priority != nil {
|
|
repoCustomization.Priority = repo.Priority
|
|
}
|
|
|
|
repoCustomizations = append(repoCustomizations, repoCustomization)
|
|
}
|
|
if bp.Customizations == nil {
|
|
bp.Customizations = &blueprint.Customizations{
|
|
Repositories: repoCustomizations,
|
|
}
|
|
} else {
|
|
bp.Customizations.Repositories = repoCustomizations
|
|
}
|
|
}
|
|
return bp, nil
|
|
}
|
|
|
|
// GetPayloadRepositories returns the custom repos
|
|
// If there are none it returns a nil slice
|
|
func (request *ComposeRequest) GetPayloadRepositories() (repos []Repository) {
|
|
if request.Customizations != nil && request.Customizations.PayloadRepositories != nil {
|
|
repos = *request.Customizations.PayloadRepositories
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// GetSubscription returns an ImageOptions struct populated by the subscription information
|
|
// included in the request, or nil if it has not been included.
|
|
func (request *ComposeRequest) GetSubscription() (sub *subscription.ImageOptions) {
|
|
if request.Customizations != nil && request.Customizations.Subscription != nil {
|
|
// Rhc is optional, default to false if not included
|
|
var rhc bool
|
|
if request.Customizations.Subscription.Rhc != nil {
|
|
rhc = *request.Customizations.Subscription.Rhc
|
|
}
|
|
sub = &subscription.ImageOptions{
|
|
Organization: request.Customizations.Subscription.Organization,
|
|
ActivationKey: request.Customizations.Subscription.ActivationKey,
|
|
ServerUrl: request.Customizations.Subscription.ServerUrl,
|
|
BaseUrl: request.Customizations.Subscription.BaseUrl,
|
|
Insights: request.Customizations.Subscription.Insights,
|
|
Rhc: rhc,
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|