target: move Filename from target options to Target
The filename of the image as produced by osbuild for a given export is currently set in each target options type in the `Filename` struct member. However, the value is not really specific to any target type, but to the specific export used for the target. For this reason move the value form target type options to the `Target` struct inside a new struct `OsbuildArtifact` under the name`ExportFilename`. The backward compatibility with older implementations of the composer and workers is kept on the JSON (Un)mashaling level, where the JSON object is always a super-set of the old and new way of providing the export filename in the Target.
This commit is contained in:
parent
eda691971c
commit
6f464949f5
18 changed files with 567 additions and 129 deletions
|
|
@ -11,13 +11,25 @@ import (
|
|||
|
||||
type TargetName string
|
||||
|
||||
// OsbuildArtifact represents a configuration to produce osbuild artifact
|
||||
// specific to a target.
|
||||
type OsbuildArtifact struct {
|
||||
// Filename of the image as produced by osbuild for a given export
|
||||
ExportFilename string `json:"export_filename"`
|
||||
}
|
||||
|
||||
type Target struct {
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
ImageName string `json:"image_name"` // Desired name of the image in the target environment
|
||||
Name TargetName `json:"name"` // Name of the specific target type
|
||||
Created time.Time `json:"created"`
|
||||
Status common.ImageBuildState `json:"status"`
|
||||
Options TargetOptions `json:"options"` // Target type specific options
|
||||
Uuid uuid.UUID `json:"uuid"`
|
||||
// Desired name of the image in the target environment
|
||||
ImageName string `json:"image_name"`
|
||||
// Name of the specific target type
|
||||
Name TargetName `json:"name"`
|
||||
Created time.Time `json:"created"`
|
||||
Status common.ImageBuildState `json:"status"`
|
||||
// Target type specific options
|
||||
Options TargetOptions `json:"options"`
|
||||
// Configuration to produce osbuild artifact specific to this target
|
||||
OsbuildArtifact OsbuildArtifact `json:"osbuild_artifact"`
|
||||
}
|
||||
|
||||
func newTarget(name TargetName, options TargetOptions) *Target {
|
||||
|
|
@ -41,6 +53,8 @@ type rawTarget struct {
|
|||
Created time.Time `json:"created"`
|
||||
Status common.ImageBuildState `json:"status"`
|
||||
Options json.RawMessage `json:"options"`
|
||||
// Configuration to produce osbuild artifact specific to this target
|
||||
OsbuildArtifact OsbuildArtifact `json:"osbuild_artifact"`
|
||||
}
|
||||
|
||||
func (target *Target) UnmarshalJSON(data []byte) error {
|
||||
|
|
@ -49,24 +63,9 @@ func (target *Target) UnmarshalJSON(data []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options, err := UnmarshalTargetOptions(rawTarget.Name, rawTarget.Options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
target.Uuid = rawTarget.Uuid
|
||||
target.ImageName = rawTarget.ImageName
|
||||
target.Name = rawTarget.Name
|
||||
target.Created = rawTarget.Created
|
||||
target.Status = rawTarget.Status
|
||||
target.Options = options
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalTargetOptions(targetName TargetName, rawOptions json.RawMessage) (TargetOptions, error) {
|
||||
var options TargetOptions
|
||||
switch targetName {
|
||||
switch rawTarget.Name {
|
||||
case TargetNameAzure:
|
||||
options = new(AzureTargetOptions)
|
||||
case TargetNameAWS:
|
||||
|
|
@ -89,9 +88,191 @@ func UnmarshalTargetOptions(targetName TargetName, rawOptions json.RawMessage) (
|
|||
case TargetNameContainer:
|
||||
options = new(ContainerTargetOptions)
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected target name: %s", targetName)
|
||||
return fmt.Errorf("unexpected target name: %s", rawTarget.Name)
|
||||
}
|
||||
err := json.Unmarshal(rawOptions, options)
|
||||
|
||||
return options, err
|
||||
err = json.Unmarshal(rawTarget.Options, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
target.Uuid = rawTarget.Uuid
|
||||
target.ImageName = rawTarget.ImageName
|
||||
target.OsbuildArtifact = rawTarget.OsbuildArtifact
|
||||
target.Name = rawTarget.Name
|
||||
target.Created = rawTarget.Created
|
||||
target.Status = rawTarget.Status
|
||||
target.Options = options
|
||||
|
||||
type compatOptionsType struct {
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
|
||||
var compat compatOptionsType
|
||||
err = json.Unmarshal(rawTarget.Options, &compat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Kept for backward compatibility
|
||||
// If the `ExportTarget` is not set in the `Target`, the request is most probably
|
||||
// coming from an old composer. Copy the value from the target options.
|
||||
if target.OsbuildArtifact.ExportFilename == "" {
|
||||
target.OsbuildArtifact.ExportFilename = compat.Filename
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (target Target) MarshalJSON() ([]byte, error) {
|
||||
// We can't use composition of the `TargetOptions` interface into a compatibility
|
||||
// structure, because the value assigned to the embedded interface type member
|
||||
// would get marshaled under the name of the type.
|
||||
var rawOptions []byte
|
||||
var err error
|
||||
if target.Options != nil {
|
||||
switch t := target.Options.(type) {
|
||||
case *AWSTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*AWSTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
AWSTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *AWSS3TargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*AWSS3TargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
AWSS3TargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *AzureTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*AzureTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
AzureTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *GCPTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*GCPTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
GCPTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *AzureImageTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*AzureImageTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
AzureImageTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
// Kept for backward compatibility
|
||||
case *LocalTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*LocalTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
LocalTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *KojiTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*KojiTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
KojiTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *VMWareTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*VMWareTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
VMWareTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *OCITargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*OCITargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
OCITargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
case *ContainerTargetOptions:
|
||||
type compatOptionsType struct {
|
||||
*ContainerTargetOptions
|
||||
// Deprecated: `Filename` is now set in the target itself as `ExportFilename`, not in its options.
|
||||
Filename string `json:"filename"`
|
||||
}
|
||||
compat := compatOptionsType{
|
||||
ContainerTargetOptions: t,
|
||||
Filename: target.OsbuildArtifact.ExportFilename,
|
||||
}
|
||||
rawOptions, err = json.Marshal(compat)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected target options type: %t", t)
|
||||
}
|
||||
|
||||
// check error from marshaling
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
alias := rawTarget{
|
||||
Uuid: target.Uuid,
|
||||
ImageName: target.ImageName,
|
||||
OsbuildArtifact: target.OsbuildArtifact,
|
||||
Name: target.Name,
|
||||
Created: target.Created,
|
||||
Status: target.Status,
|
||||
Options: json.RawMessage(rawOptions),
|
||||
}
|
||||
|
||||
return json.Marshal(alias)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue