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  }