Example #1
0
func (*SymlinkSuite) TestReplace(c *gc.C) {
	target, err := symlink.GetLongPathAsString(c.MkDir())
	c.Assert(err, gc.IsNil)
	target_second, err := symlink.GetLongPathAsString(c.MkDir())
	c.Assert(err, gc.IsNil)
	link := filepath.Join(target, "link")

	_, err = os.Stat(target)
	c.Assert(err, gc.IsNil)
	_, err = os.Stat(target_second)
	c.Assert(err, gc.IsNil)

	err = symlink.New(target, link)
	c.Assert(err, gc.IsNil)

	link_target, err := symlink.Read(link)
	c.Assert(err, gc.IsNil)
	c.Assert(link_target, gc.Equals, filepath.FromSlash(target))

	err = symlink.Replace(link, target_second)
	c.Assert(err, gc.IsNil)

	link_target, err = symlink.Read(link)
	c.Assert(err, gc.IsNil)
	c.Assert(link_target, gc.Equals, filepath.FromSlash(target_second))
}
Example #2
0
func (s *ToolsSuite) TestEnsureJujucSymlinks(c *gc.C) {
	jujudPath := filepath.Join(s.toolsDir, names.Jujud)
	err := ioutil.WriteFile(jujudPath, []byte("assume sane"), 0755)
	c.Assert(err, gc.IsNil)

	assertLink := func(path string) time.Time {
		target, err := symlink.Read(path)
		c.Assert(err, gc.IsNil)
		c.Assert(target, gc.Equals, jujudPath)
		fi, err := os.Lstat(path)
		c.Assert(err, gc.IsNil)
		return fi.ModTime()
	}

	// Check that EnsureJujucSymlinks writes appropriate symlinks.
	err = uniter.EnsureJujucSymlinks(s.toolsDir)
	c.Assert(err, gc.IsNil)
	mtimes := map[string]time.Time{}
	for _, name := range jujuc.CommandNames() {
		tool := filepath.Join(s.toolsDir, name)
		mtimes[tool] = assertLink(tool)
	}

	// Check that EnsureJujucSymlinks doesn't overwrite things that don't need to be.
	err = uniter.EnsureJujucSymlinks(s.toolsDir)
	c.Assert(err, gc.IsNil)
	for tool, mtime := range mtimes {
		c.Assert(assertLink(tool), gc.Equals, mtime)
	}
}
Example #3
0
// gitManifest returns every file path in the supplied directory, *except* for:
//    * paths below .git, because we don't need to track every file: we just
//      want them all gone
//    * charmURLPath, because we don't ever want to remove that: that's how
//      the manifestDeployer keeps track of what version it's upgrading from.
// All paths are slash-separated, to match the bundle manifest format.
func gitManifest(linkPath string) (set.Strings, error) {
	dirPath, err := symlink.Read(linkPath)
	if err != nil {
		return nil, err
	}
	manifest := make(set.Strings)
	err = filepath.Walk(dirPath, func(path string, fileInfo os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		relPath, err := filepath.Rel(dirPath, path)
		if err != nil {
			return err
		}
		switch relPath {
		case ".", CharmURLPath:
			return nil
		case ".git":
			err = filepath.SkipDir
		}
		manifest.Add(filepath.ToSlash(relPath))
		return err
	})
	return manifest, err
}
Example #4
0
func (s *MachineSuite) TestMachineAgentSymlinkJujuRunExists(c *gc.C) {
	if runtime.GOOS == "windows" {
		// Cannot make symlink to nonexistent file on windows or
		// create a file point a symlink to it then remove it
		c.Skip("Cannot test this on windows")
	}

	stm, _, _ := s.primeAgent(c, state.JobManageModel)
	a := s.newAgent(c, stm)
	defer a.Stop()

	// Pre-create the symlinks, but pointing to the incorrect location.
	links := []string{jujuRun, jujuDumpLogs}
	a.rootDir = c.MkDir()
	for _, link := range links {
		fullLink := utils.EnsureBaseDir(a.rootDir, link)
		c.Assert(os.MkdirAll(filepath.Dir(fullLink), os.FileMode(0755)), jc.ErrorIsNil)
		c.Assert(symlink.New("/nowhere/special", fullLink), jc.ErrorIsNil, gc.Commentf(link))
	}

	// Start the agent and wait for it be running.
	_, done := s.waitForOpenState(c, a)

	// juju-run symlink should have been recreated.
	for _, link := range links {
		fullLink := utils.EnsureBaseDir(a.rootDir, link)
		linkTarget, err := symlink.Read(fullLink)
		c.Assert(err, jc.ErrorIsNil)
		c.Assert(linkTarget, gc.Not(gc.Equals), "/nowhere/special", gc.Commentf(link))
	}

	s.waitStopped(c, state.JobManageModel, a, done)
}
Example #5
0
// collectGitOrphans deletes all repos in dataPath except the one pointed to by
// a git deployer's "current" symlink.
// Errors are generally ignored; some are logged. If current does not exist, *all*
// repos are orphans, and all will be deleted; this should only be the case when
// converting a gitDeployer to a manifestDeployer.
func collectGitOrphans(dataPath string) {
	current, err := symlink.Read(filepath.Join(dataPath, gitCurrentPath))
	if os.IsNotExist(err) {
		logger.Debugf("no current staging repo")
	} else if err != nil {
		logger.Warningf("cannot read current staging repo: %v", err)
		return
	} else if !filepath.IsAbs(current) {
		current = filepath.Join(dataPath, current)
	}
	orphans, err := filepath.Glob(filepath.Join(dataPath, fmt.Sprintf("%s*", gitUpdatePrefix)))
	if err != nil {
		return
	}
	installOrphans, err := filepath.Glob(filepath.Join(dataPath, fmt.Sprintf("%s*", gitInstallPrefix)))
	if err != nil {
		return
	}
	orphans = append(orphans, installOrphans...)
	for _, repoPath := range orphans {
		if repoPath != dataPath && repoPath != current {
			if err = os.RemoveAll(repoPath); err != nil {
				logger.Warningf("failed to remove orphan repo at %s: %s", repoPath, err)
			}
		}
	}
}
Example #6
0
func (s *MachineSuite) TestMachineAgentSymlinkJujuRunExists(c *gc.C) {
	err := symlink.New("/nowhere/special", jujuRun)
	c.Assert(err, gc.IsNil)
	_, err = os.Stat(jujuRun)
	c.Assert(err, jc.Satisfies, os.IsNotExist)
	s.assertJobWithAPI(c, state.JobManageEnviron, func(conf agent.Config, st *api.State) {
		// juju-run should have been recreated
		_, err := os.Stat(jujuRun)
		c.Assert(err, gc.IsNil)
		link, err := symlink.Read(jujuRun)
		c.Assert(err, gc.IsNil)
		c.Assert(link, gc.Not(gc.Equals), "/nowhere/special")
	})
}
Example #7
0
func (*SymlinkSuite) TestCreateSymLink(c *gc.C) {
	target, err := symlink.GetLongPathAsString(c.MkDir())
	c.Assert(err, gc.IsNil)

	link := filepath.Join(target, "link")

	_, err = os.Stat(target)
	c.Assert(err, gc.IsNil)

	err = symlink.New(target, link)
	c.Assert(err, gc.IsNil)

	link, err = symlink.Read(link)
	c.Assert(err, gc.IsNil)
	c.Assert(link, gc.Equals, filepath.FromSlash(target))
}
Example #8
0
func (s *LxcSuite) TestCreateContainer(c *gc.C) {
	manager := s.makeManager(c, "test")
	instance := containertesting.CreateContainer(c, manager, "1/lxc/0")

	name := string(instance.Id())
	// Check our container config files: initial lxc.conf, the
	// run-time effective config, and cloud-init userdata.
	lxcConfContents, err := ioutil.ReadFile(filepath.Join(s.ContainerDir, name, "lxc.conf"))
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(string(lxcConfContents), jc.Contains, "lxc.network.link = nic42")
	lxcConfContents, err = ioutil.ReadFile(lxc.ContainerConfigFilename(name))
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(string(lxcConfContents), jc.Contains, "lxc.network.link = nic42")

	cloudInitFilename := filepath.Join(s.ContainerDir, name, "cloud-init")
	data := containertesting.AssertCloudInit(c, cloudInitFilename)

	x := make(map[interface{}]interface{})
	err = goyaml.Unmarshal(data, &x)
	c.Assert(err, jc.ErrorIsNil)

	var scripts []string
	for _, s := range x["runcmd"].([]interface{}) {
		scripts = append(scripts, s.(string))
	}

	c.Assert(scripts[len(scripts)-3:], gc.DeepEquals, []string{
		"start jujud-machine-1-lxc-0",
		"rm $bin/tools.tar.gz && rm $bin/juju2.3.4-quantal-amd64.sha256",
		"ifconfig",
	})

	// Check the mount point has been created inside the container.
	c.Assert(filepath.Join(s.LxcDir, name, "rootfs", agent.DefaultPaths.LogDir), jc.IsDirectory)
	// Check that the config file is linked in the restart dir.
	expectedLinkLocation := filepath.Join(s.RestartDir, name+".conf")
	expectedTarget := filepath.Join(s.LxcDir, name, "config")
	linkInfo, err := os.Lstat(expectedLinkLocation)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(linkInfo.Mode()&os.ModeSymlink, gc.Equals, os.ModeSymlink)

	location, err := symlink.Read(expectedLinkLocation)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(location, gc.Equals, expectedTarget)
}
Example #9
0
func checkCleanup(c *gc.C, d charm.Deployer) {
	// Only one update dir should exist and be pointed to by the 'current'
	// symlink since extra ones should have been cleaned up by
	// cleanupOrphans.
	deployerPath := charm.GitDeployerDataPath(d)
	updateDirs, err := filepath.Glob(filepath.Join(deployerPath, "update-*"))
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(updateDirs, gc.HasLen, 1)
	deployerCurrent := charm.GitDeployerCurrent(d)
	current, err := symlink.Read(deployerCurrent.Path())
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(updateDirs[0], gc.Equals, current)

	// No install dirs should be left behind since the one created is
	// renamed to the target path.
	installDirs, err := filepath.Glob(filepath.Join(deployerPath, "install-*"))
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(installDirs, gc.HasLen, 0)
}
Example #10
0
func (s *UpgraderSuite) TestChangeAgentTools(c *gc.C) {
	oldTools := &coretools.Tools{
		Version: version.MustParseBinary("1.2.3-quantal-amd64"),
	}
	stor := s.Conn.Environ.Storage()
	newTools := envtesting.PrimeTools(c, stor, s.DataDir(), version.MustParseBinary("5.4.3-precise-amd64"))
	s.PatchValue(&version.Current, newTools.Version)
	err := envtools.MergeAndWriteMetadata(stor, coretools.List{newTools}, envtools.DoNotWriteMirrors)
	c.Assert(err, gc.IsNil)
	ugErr := &upgrader.UpgradeReadyError{
		AgentName: "anAgent",
		OldTools:  oldTools.Version,
		NewTools:  newTools.Version,
		DataDir:   s.DataDir(),
	}
	err = ugErr.ChangeAgentTools()
	c.Assert(err, gc.IsNil)
	link, err := symlink.Read(agenttools.ToolsDir(s.DataDir(), "anAgent"))
	c.Assert(err, gc.IsNil)
	c.Assert(link, gc.Equals, newTools.Version.String())
}
Example #11
0
func (s *UpgraderSuite) TestChangeAgentTools(c *gc.C) {
	oldTools := &coretools.Tools{
		Version: version.MustParseBinary("1.2.3-quantal-amd64"),
	}
	stor := s.DefaultToolsStorage
	newToolsBinary := "5.4.3-precise-amd64"
	newTools := envtesting.PrimeTools(c, stor, s.DataDir(), s.Environ.Config().AgentStream(), version.MustParseBinary(newToolsBinary))
	s.PatchValue(&version.Current, newTools.Version)
	err := envtools.MergeAndWriteMetadata(stor, "released", "released", coretools.List{newTools}, envtools.DoNotWriteMirrors)
	c.Assert(err, jc.ErrorIsNil)
	ugErr := &upgrader.UpgradeReadyError{
		AgentName: "anAgent",
		OldTools:  oldTools.Version,
		NewTools:  newTools.Version,
		DataDir:   s.DataDir(),
	}
	err = ugErr.ChangeAgentTools()
	c.Assert(err, jc.ErrorIsNil)
	target := agenttools.ToolsDir(s.DataDir(), newToolsBinary)
	link, err := symlink.Read(agenttools.ToolsDir(s.DataDir(), "anAgent"))
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(link, jc.SamePath, target)
}
Example #12
0
func (a *MachineAgent) createSymlink(target, link string) error {
	fullLink := utils.EnsureBaseDir(a.rootDir, link)

	currentTarget, err := symlink.Read(fullLink)
	if err != nil && !os.IsNotExist(err) {
		return err
	} else if err == nil {
		// Link already in place - check it.
		if currentTarget == target {
			// Link already points to the right place - nothing to do.
			return nil
		}
		// Link points to the wrong place - delete it.
		if err := os.Remove(fullLink); err != nil {
			return err
		}
	}

	if err := os.MkdirAll(filepath.Dir(fullLink), os.FileMode(0755)); err != nil {
		return err
	}
	return symlink.New(target, fullLink)
}
Example #13
0
// EnsureSymlinks creates a symbolic link to jujuc within dir for each
// hook command. If the commands already exist, this operation does nothing.
// If dir is a symbolic link, it will be dereferenced first.
func EnsureSymlinks(dir string) (err error) {
	logger.Infof("ensure jujuc symlinks in %s", dir)
	defer func() {
		if err != nil {
			err = errors.Annotatef(err, "cannot initialize hook commands in %q", dir)
		}
	}()
	isSymlink, err := symlink.IsSymlink(dir)
	if err != nil {
		return err
	}
	if isSymlink {
		link, err := symlink.Read(dir)
		if err != nil {
			return err
		}
		if !filepath.IsAbs(link) {
			logger.Infof("%s is relative", link)
			link = filepath.Join(filepath.Dir(dir), link)
		}
		dir = link
		logger.Infof("was a symlink, now looking at %s", dir)
	}

	jujudPath := filepath.Join(dir, names.Jujud)
	logger.Debugf("jujud path %s", jujudPath)
	for _, name := range CommandNames() {
		// The link operation fails when the target already exists,
		// so this is a no-op when the command names already
		// exist.
		err := symlink.New(jujudPath, filepath.Join(dir, name))
		if err != nil && !os.IsExist(err) {
			return err
		}
	}
	return nil
}