66
68
// use for the given service.
71
// Series is the series to use when deploying a local charm,
72
// if the charm does not specify a default or the default
73
// is not the desired value.
74
// Series is not compatible with charm store charms where
75
// the series is specified in the URL.
76
Series string `yaml:",omitempty" json:",omitempty"`
78
// Resources is the set of resource revisions to deploy for the
79
// service. Bundles only support charm store resources and not ones
80
// that were uploaded to the controller.
81
Resources map[string]int `yaml:",omitempty" json:",omitempty"`
69
83
// NumUnits holds the number of units of the
70
84
// service that will be deployed.
236
// VerifyLocal verifies that a local bundle file is consistent.
237
// A local bundle file may contain references to charms which are
238
// referred to by a directory, either relative or absolute.
240
// bundleDir is used to construct the full path for charms specified
241
// using a relative directory path. The charm path is therefore expected
242
// to be relative to the bundle.yaml file.
243
func (bd *BundleData) VerifyLocal(
245
verifyConstraints func(c string) error,
246
verifyStorage func(s string) error,
248
return bd.verifyBundle(bundleDir, verifyConstraints, verifyStorage, nil)
220
251
// Verify is a convenience method that calls VerifyWithCharms
221
252
// with a nil charms map.
222
253
func (bd *BundleData) Verify(
252
283
verifyStorage func(s string) error,
253
284
charms map[string]Charm,
286
return bd.verifyBundle("", verifyConstraints, verifyStorage, charms)
289
func (bd *BundleData) verifyBundle(
291
verifyConstraints func(c string) error,
292
verifyStorage func(s string) error,
293
charms map[string]Charm,
255
295
if verifyConstraints == nil {
256
296
verifyConstraints = func(string) error {
321
362
for name, svc := range verifier.bd.Services {
322
if _, err := ParseURL(svc.Charm); err != nil {
364
verifier.addErrorf("empty charm path")
366
// Charm may be a local directory or a charm URL.
369
if strings.HasPrefix(svc.Charm, ".") || filepath.IsAbs(svc.Charm) {
370
charmPath := svc.Charm
371
if !filepath.IsAbs(charmPath) {
372
charmPath = filepath.Join(verifier.bundleDir, charmPath)
374
if _, err := os.Stat(charmPath); err != nil {
375
if os.IsNotExist(err) {
376
verifier.addErrorf("charm path in service %q does not exist: %v", name, charmPath)
378
verifier.addErrorf("invalid charm path in service %q: %v", name, err)
381
} else if curl, err = ParseURL(svc.Charm); err != nil {
323
382
verifier.addErrorf("invalid charm URL in service %q: %v", name, err)
386
if curl != nil && curl.Series != "" && svc.Series != "" && curl.Series != svc.Series {
387
verifier.addErrorf("the charm URL for service %q has a series which does not match, please remove the series from the URL", name)
389
if svc.Series != "" && !IsValidSeries(svc.Series) {
390
verifier.addErrorf("service %q declares an invalid series %q", name, svc.Series)
325
393
if err := verifier.verifyConstraints(svc.Constraints); err != nil {
326
394
verifier.addErrorf("invalid constraints %q in service %q: %v", svc.Constraints, name, err)
347
415
verifier.addErrorf("service %q refers to non-existent charm %q", name, svc.Charm)
418
for resName := range svc.Resources {
420
verifier.addErrorf("missing resource name on service %q", name)
422
// We do not check the revisions because all values
350
425
if svc.NumUnits < 0 {
351
426
verifier.addErrorf("negative number of units specified on service %q", name)
352
427
} else if len(svc.To) > svc.NumUnits {
469
544
for endpoint, space := range svc.EndpointBindings {
470
_, matchedProvides := charm.Meta().Provides[endpoint]
471
_, matchedRequires := charm.Meta().Requires[endpoint]
472
_, matchedPeers := charm.Meta().Peers[endpoint]
545
_, isInProvides := charm.Meta().Provides[endpoint]
546
_, isInRequires := charm.Meta().Requires[endpoint]
547
_, isInPeers := charm.Meta().Peers[endpoint]
548
_, isInExtraBindings := charm.Meta().ExtraBindings[endpoint]
474
if !(matchedProvides || matchedRequires || matchedPeers) {
550
if !(isInProvides || isInRequires || isInPeers || isInExtraBindings) {
475
551
verifier.addErrorf(
476
552
"service %q wants to bind endpoint %q to space %q, "+
477
553
"but the endpoint is not defined by the charm",