Example #1
0
func (s createCharm) step(c *gc.C, ctx *context) {
	base := testcharms.Repo.ClonedDirPath(c.MkDir(), "wordpress")

	allCharmHooks := baseCharmHooks
	allCharmHooks = append(allCharmHooks, leaderCharmHooks...)
	allCharmHooks = append(allCharmHooks, storageCharmHooks...)

	for _, name := range allCharmHooks {
		path := filepath.Join(base, "hooks", name)
		good := true
		for _, bad := range s.badHooks {
			if name == bad {
				good = false
			}
		}
		ctx.writeHook(c, path, good)
	}
	if s.customize != nil {
		s.customize(c, ctx, base)
	}
	dir, err := corecharm.ReadCharmDir(base)
	c.Assert(err, jc.ErrorIsNil)
	err = dir.SetDiskRevision(s.revision)
	c.Assert(err, jc.ErrorIsNil)
	step(c, ctx, addCharm{dir, curl(s.revision)})
}
Example #2
0
// initializeMetricsCollector enables the periodic collect-metrics hook
// for charms that declare metrics.
func (u *Uniter) initializeMetricsCollector() error {
	charm, err := corecharm.ReadCharmDir(u.paths.State.CharmDir)
	if err != nil {
		return err
	}
	u.collectMetricsAt = u.metricsTimerChooser.getMetricsTimer(charm)
	return nil
}
Example #3
0
func (br *bundleReader) AddCustomBundle(c *gc.C, url *corecharm.URL, customize func(path string)) charm.BundleInfo {
	base := c.MkDir()
	dirpath := testcharms.Repo.ClonedDirPath(base, "dummy")
	if customize != nil {
		customize(dirpath)
	}
	dir, err := corecharm.ReadCharmDir(dirpath)
	c.Assert(err, jc.ErrorIsNil)
	err = dir.SetDiskRevision(url.Revision)
	c.Assert(err, jc.ErrorIsNil)
	bunpath := filepath.Join(base, "bundle")
	file, err := os.Create(bunpath)
	c.Assert(err, jc.ErrorIsNil)
	defer file.Close()
	err = dir.ArchiveTo(file)
	c.Assert(err, jc.ErrorIsNil)
	bundle, err := corecharm.ReadCharmArchive(bunpath)
	c.Assert(err, jc.ErrorIsNil)
	return br.AddBundle(c, url, bundle)
}
Example #4
0
// Update is part of the Relations interface.
func (r *relations) Update(ids []int) error {
	for _, id := range ids {
		if relationer, found := r.relationers[id]; found {
			rel := relationer.ru.Relation()
			if err := rel.Refresh(); err != nil {
				return errors.Annotatef(err, "cannot update relation %q", rel)
			}
			if rel.Life() == params.Dying {
				if err := r.setDying(id); err != nil {
					return errors.Trace(err)
				}
			}
			continue
		}
		// Relations that are not alive are simply skipped, because they
		// were not previously known anyway.
		rel, err := r.st.RelationById(id)
		if err != nil {
			if params.IsCodeNotFoundOrCodeUnauthorized(err) {
				continue
			}
			return errors.Trace(err)
		}
		if rel.Life() != params.Alive {
			continue
		}
		// Make sure we ignore relations not implemented by the unit's charm.
		ch, err := corecharm.ReadCharmDir(r.charmDir)
		if err != nil {
			return errors.Trace(err)
		}
		if ep, err := rel.Endpoint(); err != nil {
			return errors.Trace(err)
		} else if !ep.ImplementedBy(ch) {
			logger.Warningf("skipping relation with unknown endpoint %q", ep.Name)
			continue
		}
		dir, err := relation.ReadStateDir(r.relationsDir, id)
		if err != nil {
			return errors.Trace(err)
		}
		err = r.add(rel, dir)
		if err == nil {
			r.relationers[id].StartHooks()
			continue
		}
		e := dir.Remove()
		if !params.IsCodeCannotEnterScope(err) {
			return errors.Trace(err)
		}
		if e != nil {
			return errors.Trace(e)
		}
	}
	if ok, err := r.unit.IsPrincipal(); err != nil {
		return errors.Trace(err)
	} else if ok {
		return nil
	}
	// If no Alive relations remain between a subordinate unit's service
	// and its principal's service, the subordinate must become Dying.
	for _, relationer := range r.relationers {
		scope := relationer.ru.Endpoint().Scope
		if scope == corecharm.ScopeContainer && !relationer.dying {
			return nil
		}
	}
	return r.unit.Destroy()
}
Example #5
0
func (r *relations) update(remote map[int]remotestate.RelationSnapshot) error {
	for id, relationSnapshot := range remote {
		if _, found := r.relationers[id]; found {
			// We've seen this relation before. The only changes
			// we care about are to the lifecycle state, and to
			// the member settings versions. We handle differences
			// in settings in nextRelationHook.
			if relationSnapshot.Life == params.Dying {
				if err := r.setDying(id); err != nil {
					return errors.Trace(err)
				}
			}
			continue
		}
		// Relations that are not alive are simply skipped, because they
		// were not previously known anyway.
		if relationSnapshot.Life != params.Alive {
			continue
		}
		rel, err := r.st.RelationById(id)
		if err != nil {
			if params.IsCodeNotFoundOrCodeUnauthorized(err) {
				continue
			}
			return errors.Trace(err)
		}
		// Make sure we ignore relations not implemented by the unit's charm.
		ch, err := corecharm.ReadCharmDir(r.charmDir)
		if err != nil {
			return errors.Trace(err)
		}
		if ep, err := rel.Endpoint(); err != nil {
			return errors.Trace(err)
		} else if !ep.ImplementedBy(ch) {
			logger.Warningf("skipping relation with unknown endpoint %q", ep.Name)
			continue
		}
		dir, err := ReadStateDir(r.relationsDir, id)
		if err != nil {
			return errors.Trace(err)
		}
		addErr := r.add(rel, dir)
		if addErr == nil {
			continue
		}
		removeErr := dir.Remove()
		if !params.IsCodeCannotEnterScope(addErr) {
			return errors.Trace(addErr)
		}
		if removeErr != nil {
			return errors.Trace(removeErr)
		}
	}
	if ok, err := r.unit.IsPrincipal(); err != nil {
		return errors.Trace(err)
	} else if ok {
		return nil
	}
	// If no Alive relations remain between a subordinate unit's service
	// and its principal's service, the subordinate must become Dying.
	for _, relationer := range r.relationers {
		scope := relationer.ru.Endpoint().Scope
		if scope == corecharm.ScopeContainer && !relationer.dying {
			return nil
		}
	}
	return r.unit.Destroy()
}