func (s *DeployerSuite) TestInstall(c *C) { // Install. d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer")) bun := s.bundle(c, func(path string) { err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644) c.Assert(err, IsNil) }) err := d.Stage(bun, corecharm.MustParseURL("cs:s/c-1")) c.Assert(err, IsNil) target := charm.NewGitDir(filepath.Join(c.MkDir(), "target")) err = d.Deploy(target) c.Assert(err, IsNil) // Check content. data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file")) c.Assert(err, IsNil) c.Assert(string(data), Equals, "hello") url, err := charm.ReadCharmURL(target) c.Assert(err, IsNil) c.Assert(url, DeepEquals, corecharm.MustParseURL("cs:s/c-1")) lines, err := target.Log() c.Assert(err, IsNil) c.Assert(lines, HasLen, 2) c.Assert(lines[0], Matches, `[0-9a-f]{7} Deployed charm "cs:s/c-1".`) c.Assert(lines[1], Matches, `[0-9a-f]{7} Imported charm "cs:s/c-1" from ".*".`) }
// ModeAbide is the Uniter's usual steady state. It watches for and responds to: // * service configuration changes // * charm upgrade requests // * relation changes // * unit death func ModeAbide(u *Uniter) (next Mode, err error) { defer modeContext("ModeAbide", &err)() if u.s.Op != Continue { return nil, fmt.Errorf("insane uniter state: %#v", u.s) } if err = u.unit.SetStatus(state.UnitStarted, ""); err != nil { return nil, err } url, err := charm.ReadCharmURL(u.charm) if err != nil { return nil, err } u.f.WantUpgradeEvent(url, false) for _, r := range u.relationers { r.StartHooks() } defer func() { for _, r := range u.relationers { if e := r.StopHooks(); e != nil && err == nil { err = e } } }() select { case <-u.f.UnitDying(): return modeAbideDyingLoop(u) default: } return modeAbideAliveLoop(u) }
func (s *GitDirSuite) TestAddCommitPullRevert(c *C) { target := charm.NewGitDir(c.MkDir()) err := target.Init() c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(target.Path(), "initial"), []byte("initial"), 0644) c.Assert(err, IsNil) err = charm.WriteCharmURL(target, curl) c.Assert(err, IsNil) err = target.AddAll() c.Assert(err, IsNil) dirty, err := target.Dirty() c.Assert(err, IsNil) c.Assert(dirty, Equals, true) err = target.Commitf("initial") c.Assert(err, IsNil) dirty, err = target.Dirty() c.Assert(err, IsNil) c.Assert(dirty, Equals, false) source := newRepo(c) err = target.Pull(source) c.Assert(err, IsNil) url, err := charm.ReadCharmURL(target) c.Assert(err, IsNil) c.Assert(url, DeepEquals, curl) fi, err := os.Stat(filepath.Join(target.Path(), "some-dir")) c.Assert(err, IsNil) c.Assert(fi, checkers.Satisfies, os.FileInfo.IsDir) data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file")) c.Assert(err, IsNil) c.Assert(string(data), Equals, "hello") dirty, err = target.Dirty() c.Assert(err, IsNil) c.Assert(dirty, Equals, false) err = ioutil.WriteFile(filepath.Join(target.Path(), "another-file"), []byte("blah"), 0644) c.Assert(err, IsNil) dirty, err = target.Dirty() c.Assert(err, IsNil) c.Assert(dirty, Equals, true) err = source.AddAll() c.Assert(err, IsNil) dirty, err = target.Dirty() c.Assert(err, IsNil) c.Assert(dirty, Equals, true) err = target.Revert() c.Assert(err, IsNil) _, err = os.Stat(filepath.Join(target.Path(), "some-file")) c.Assert(err, checkers.Satisfies, os.IsNotExist) _, err = os.Stat(filepath.Join(target.Path(), "some-dir")) c.Assert(err, checkers.Satisfies, os.IsNotExist) data, err = ioutil.ReadFile(filepath.Join(target.Path(), "initial")) c.Assert(err, IsNil) c.Assert(string(data), Equals, "initial") dirty, err = target.Dirty() c.Assert(err, IsNil) c.Assert(dirty, Equals, false) }
// ModeHookError is responsible for watching and responding to: // * user resolution of hook errors // * charm upgrade requests func ModeHookError(u *Uniter) (next Mode, err error) { defer modeContext("ModeHookError", &err)() if u.s.Op != RunHook || u.s.OpStep != Pending { return nil, fmt.Errorf("insane uniter state: %#v", u.s) } msg := fmt.Sprintf("hook failed: %q", u.s.Hook.Kind) if err = u.unit.SetStatus(state.UnitError, msg); err != nil { return nil, err } url, err := charm.ReadCharmURL(u.charm) if err != nil { return nil, err } u.f.WantResolvedEvent() u.f.WantUpgradeEvent(url, true) for { select { case <-u.tomb.Dying(): return nil, tomb.ErrDying case rm := <-u.f.ResolvedEvents(): switch rm { case state.ResolvedRetryHooks: err = u.runHook(*u.s.Hook) case state.ResolvedNoHooks: err = u.commitHook(*u.s.Hook) default: return nil, fmt.Errorf("unknown resolved mode %q", rm) } if e := u.unit.ClearResolved(); e != nil { return nil, e } if err == errHookFailed { continue } else if err != nil { return nil, err } return ModeContinue, nil case upgrade := <-u.f.UpgradeEvents(): return ModeUpgrading(upgrade), nil } } panic("unreachable") }
func (s *DeployerSuite) TestUpgrade(c *C) { // Install. d := charm.NewDeployer(filepath.Join(c.MkDir(), "deployer")) bun1 := s.bundle(c, func(path string) { err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("hello"), 0644) c.Assert(err, IsNil) err = os.Symlink("./some-file", filepath.Join(path, "a-symlink")) c.Assert(err, IsNil) }) err := d.Stage(bun1, corecharm.MustParseURL("cs:s/c-1")) c.Assert(err, IsNil) target := charm.NewGitDir(filepath.Join(c.MkDir(), "target")) err = d.Deploy(target) c.Assert(err, IsNil) // Upgrade. bun2 := s.bundle(c, func(path string) { err := ioutil.WriteFile(filepath.Join(path, "some-file"), []byte("goodbye"), 0644) c.Assert(err, IsNil) err = ioutil.WriteFile(filepath.Join(path, "a-symlink"), []byte("not any more!"), 0644) c.Assert(err, IsNil) }) err = d.Stage(bun2, corecharm.MustParseURL("cs:s/c-2")) c.Assert(err, IsNil) err = d.Deploy(target) c.Assert(err, IsNil) // Check content. data, err := ioutil.ReadFile(filepath.Join(target.Path(), "some-file")) c.Assert(err, IsNil) c.Assert(string(data), Equals, "goodbye") data, err = ioutil.ReadFile(filepath.Join(target.Path(), "a-symlink")) c.Assert(err, IsNil) c.Assert(string(data), Equals, "not any more!") url, err := charm.ReadCharmURL(target) c.Assert(err, IsNil) c.Assert(url, DeepEquals, corecharm.MustParseURL("cs:s/c-2")) lines, err := target.Log() c.Assert(err, IsNil) c.Assert(lines, HasLen, 5) c.Assert(lines[0], Matches, `[0-9a-f]{7} Upgraded charm to "cs:s/c-2".`) }
func (s *GitDirSuite) TestCreate(c *C) { base := c.MkDir() repo := charm.NewGitDir(filepath.Join(base, "repo")) exists, err := repo.Exists() c.Assert(err, IsNil) c.Assert(exists, Equals, false) err = ioutil.WriteFile(repo.Path(), nil, 0644) c.Assert(err, IsNil) _, err = repo.Exists() c.Assert(err, ErrorMatches, `".*/repo" is not a directory`) err = os.Remove(repo.Path()) c.Assert(err, IsNil) err = os.Chmod(base, 0555) c.Assert(err, IsNil) defer os.Chmod(base, 0755) err = repo.Init() c.Assert(err, ErrorMatches, ".* permission denied") exists, err = repo.Exists() c.Assert(err, IsNil) c.Assert(exists, Equals, false) err = os.Chmod(base, 0755) c.Assert(err, IsNil) err = repo.Init() c.Assert(err, IsNil) exists, err = repo.Exists() c.Assert(err, IsNil) c.Assert(exists, Equals, true) _, err = charm.ReadCharmURL(repo) c.Assert(err, checkers.Satisfies, os.IsNotExist) err = repo.Init() c.Assert(err, IsNil) }