github.com/docker/app@v0.9.1-beta3.0.20210611140623-a48f773ab002/internal/packager/custom.go (about) 1 package packager 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 8 "github.com/deislabs/cnab-go/bundle" 9 "github.com/docker/app/internal" 10 ) 11 12 const ( 13 // DockerAppCustomVersion1_0_0 is the custom payload version 1.0.0 14 DockerAppPayloadVersion1_0_0 = "1.0.0" 15 16 // DockerAppCustomVersionCurrent the current payload version 17 // The version must be bumped each time the Payload format change. 18 DockerAppPayloadVersionCurrent = DockerAppPayloadVersion1_0_0 19 ) 20 21 // DockerAppCustom contains extension custom data that docker app injects 22 // in the bundle. 23 type DockerAppCustom struct { 24 // Payload format version 25 Version string `json:"version,omitempty"` 26 // Custom payload format depends on version 27 Payload json.RawMessage `json:"payload,omitempty"` 28 } 29 30 // CustomPayloadAppVersion is a custom payload with a docker app version 31 type CustomPayloadAppVersion interface { 32 AppVersion() string 33 } 34 35 type payloadV1_0 struct { 36 Version string `json:"app-version"` 37 } 38 39 func (p payloadV1_0) AppVersion() string { 40 return p.Version 41 } 42 43 func newCustomPayload() (json.RawMessage, error) { 44 p := payloadV1_0{Version: internal.Version} 45 j, err := json.Marshal(&p) 46 if err != nil { 47 return nil, err 48 } 49 return j, nil 50 } 51 52 // CheckAppVersion prints a warning if the bundle was built with a different version of docker app 53 func CheckAppVersion(stderr io.Writer, bndl *bundle.Bundle) error { 54 payload, err := CustomPayload(bndl) 55 if err != nil { 56 return err 57 } 58 if payload == nil { 59 return nil 60 } 61 62 var version string 63 if versionPayload, ok := payload.(CustomPayloadAppVersion); ok { 64 version = versionPayload.AppVersion() 65 } 66 if version != internal.Version { 67 fmt.Fprintf(stderr, "WARNING: App Image has been built with a different version of docker app: %q\n", version) 68 } 69 return nil 70 } 71 72 // CustomPayload parses and returns the bundle's custom payload 73 func CustomPayload(b *bundle.Bundle) (interface{}, error) { 74 custom, err := parseCustomPayload(b) 75 if err != nil { 76 return nil, err 77 } 78 79 switch version := custom.Version; version { 80 case DockerAppPayloadVersion1_0_0: 81 var payload payloadV1_0 82 if err := json.Unmarshal(custom.Payload, &payload); err != nil { 83 return nil, err 84 } 85 return payload, nil 86 default: 87 return nil, nil 88 } 89 } 90 91 func parseCustomPayload(b *bundle.Bundle) (DockerAppCustom, error) { 92 customMap, ok := b.Custom[internal.CustomDockerAppName] 93 if !ok { 94 return DockerAppCustom{}, nil 95 } 96 97 customJSON, err := json.Marshal(customMap) 98 if err != nil { 99 return DockerAppCustom{}, err 100 } 101 102 var custom DockerAppCustom 103 if err = json.Unmarshal(customJSON, &custom); err != nil { 104 return DockerAppCustom{}, err 105 } 106 107 return custom, nil 108 }