예제 #1
0
// Write atomically writes to disk the relation state change in hi.
// It must be called after the respective hook was executed successfully.
// Write doesn't validate hi but guarantees that successive writes of
// the same hi are idempotent.
func (d *StateDir) Write(hi hook.Info) (err error) {
	defer trivial.ErrorContextf(&err, "failed to write %q hook info for %q on state directory", hi.Kind, hi.RemoteUnit)
	if hi.Kind == hook.RelationBroken {
		return d.Remove()
	}
	name := strings.Replace(hi.RemoteUnit, "/", "-", 1)
	path := filepath.Join(d.path, name)
	if hi.Kind == hook.RelationDeparted {
		if err = os.Remove(path); err != nil && !os.IsNotExist(err) {
			return err
		}
		// If atomic delete succeeded, update own state.
		delete(d.state.Members, hi.RemoteUnit)
		return nil
	}
	di := diskInfo{&hi.ChangeVersion, hi.Kind == hook.RelationJoined}
	if err := trivial.WriteYaml(path, &di); err != nil {
		return err
	}
	// If write was successful, update own state.
	d.state.Members[hi.RemoteUnit] = hi.ChangeVersion
	if hi.Kind == hook.RelationJoined {
		d.state.ChangedPending = hi.RemoteUnit
	} else {
		d.state.ChangedPending = ""
	}
	return nil
}
예제 #2
0
func (s *StateFileSuite) TestStates(c *C) {
	for i, t := range stateTests {
		c.Logf("test %d", i)
		path := filepath.Join(c.MkDir(), "uniter")
		file := uniter.NewStateFile(path)
		_, err := file.Read()
		c.Assert(err, Equals, uniter.ErrNoStateFile)
		write := func() {
			err := file.Write(t.st.Started, t.st.Op, t.st.OpStep, t.st.Hook, t.st.CharmURL)
			c.Assert(err, IsNil)
		}
		if t.err != "" {
			c.Assert(write, PanicMatches, "invalid uniter state: "+t.err)
			err := trivial.WriteYaml(path, &t.st)
			c.Assert(err, IsNil)
			_, err = file.Read()
			c.Assert(err, ErrorMatches, "cannot read charm state at .*: invalid uniter state: "+t.err)
			continue
		}
		write()
		st, err := file.Read()
		c.Assert(err, IsNil)
		if st.Hook != nil {
			c.Assert(st.Hook.Members, HasLen, 0)
			st.Hook.Members = t.st.Hook.Members
		}
		c.Assert(*st, DeepEquals, t.st)
	}
}
예제 #3
0
// Write stores the supplied state to the file.
func (f *StateFile) Write(started bool, op Op, step OpStep, hi *hook.Info, url *charm.URL) error {
	if hi != nil {
		// Strip membership info: it's potentially large, and can
		// be reconstructed from relation state when required.
		hiCopy := *hi
		hiCopy.Members = nil
		hi = &hiCopy
	}
	st := &State{
		Started:  started,
		Op:       op,
		OpStep:   step,
		Hook:     hi,
		CharmURL: url,
	}
	if err := st.validate(); err != nil {
		panic(err)
	}
	return trivial.WriteYaml(f.path, st)
}
예제 #4
0
파일: git.go 프로젝트: prabhakhar/juju-core
// WriteCharmURL writes a charm identity file into the directory.
func WriteCharmURL(d *GitDir, url *charm.URL) error {
	return trivial.WriteYaml(filepath.Join(d.path, ".juju-charm"), url.String())
}