github.com/juju/charm/v11@v11.2.0/resource/resource.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the LGPLv3, see LICENCE file for details. 3 4 package resource 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 ) 11 12 // Resource describes a charm's resource in the charm store. 13 type Resource struct { 14 Meta 15 16 // Origin identifies where the resource will come from. 17 Origin Origin 18 19 // Revision is the charm store revision of the resource. 20 Revision int 21 22 // Fingerprint is the SHA-384 checksum for the resource blob. 23 Fingerprint Fingerprint 24 25 // Size is the size of the resource, in bytes. 26 Size int64 27 } 28 29 // Validate checks the payload class to ensure its data is valid. 30 func (res Resource) Validate() error { 31 if err := res.Meta.Validate(); err != nil { 32 return errors.Annotate(err, "bad metadata") 33 } 34 35 if err := res.Origin.Validate(); err != nil { 36 return errors.Annotate(err, "bad origin") 37 } 38 39 if err := res.validateRevision(); err != nil { 40 return errors.Annotate(err, "bad revision") 41 } 42 43 if res.Type == TypeFile { 44 if err := res.validateFileInfo(); err != nil { 45 return errors.Annotate(err, "bad file info") 46 } 47 } 48 49 return nil 50 } 51 52 func (res Resource) validateRevision() error { 53 if res.Origin == OriginUpload { 54 // We do not care about the revision, so we don't check it. 55 // TODO(ericsnow) Ensure Revision is 0 for OriginUpload? 56 return nil 57 } 58 59 if res.Revision < 0 && res.isFileAvailable() { 60 return errors.NewNotValid(nil, fmt.Sprintf("must be non-negative, got %d", res.Revision)) 61 } 62 63 return nil 64 } 65 66 func (res Resource) validateFileInfo() error { 67 if res.Fingerprint.IsZero() { 68 if res.Size > 0 { 69 return errors.NewNotValid(nil, "missing fingerprint") 70 } 71 } else { 72 if err := res.Fingerprint.Validate(); err != nil { 73 return errors.Annotate(err, "bad fingerprint") 74 } 75 } 76 77 if res.Size < 0 { 78 return errors.NewNotValid(nil, "negative size") 79 } 80 81 return nil 82 } 83 84 // isFileAvailable determines whether or not the resource info indicates 85 // that the resource file is available. 86 func (res Resource) isFileAvailable() bool { 87 if !res.Fingerprint.IsZero() { 88 return true 89 } 90 if res.Size > 0 { 91 return true 92 } 93 return false 94 }