func (*format_1_16Suite) TestReadConfReadsLegacyFormatAndWritesNew(c *gc.C) {
	dataDir := c.MkDir()
	formatPath := filepath.Join(dataDir, legacyFormatFilename)
	err := utils.AtomicWriteFile(formatPath, []byte(legacyFormatFileContents), 0600)
	c.Assert(err, gc.IsNil)
	configPath := filepath.Join(dataDir, agentConfigFilename)
	err = utils.AtomicWriteFile(configPath, []byte(agentConfig1_16Contents), 0600)
	c.Assert(err, gc.IsNil)

	config, err := ReadConfig(configPath)
	c.Assert(err, gc.IsNil)
	c.Assert(config, gc.NotNil)
	// Test we wrote a currently valid config.
	config, err = ReadConfig(configPath)
	c.Assert(err, gc.IsNil)
	c.Assert(config, gc.NotNil)
	c.Assert(config.UpgradedToVersion(), jc.DeepEquals, version.MustParse("1.16.0"))
	c.Assert(config.Jobs(), gc.HasLen, 0)

	// Old format was deleted.
	assertFileNotExist(c, formatPath)
	// And new contents were written.
	data, err := ioutil.ReadFile(configPath)
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Not(gc.Equals), agentConfig1_16Contents)
}
Beispiel #2
0
// EnsureMongoServer ensures that the correct mongo upstart script is installed
// and running.
//
// This method will remove old versions of the mongo upstart script as necessary
// before installing the new version.
//
// The namespace is a unique identifier to prevent multiple instances of mongo
// on this machine from colliding. This should be empty unless using
// the local provider.
func EnsureServer(dataDir string, namespace string, info params.StateServingInfo, withHA bool) error {
	logger.Infof("Ensuring mongo server is running; data directory %s; port %d", dataDir, info.StatePort)
	dbDir := filepath.Join(dataDir, "db")

	if err := os.MkdirAll(dbDir, 0700); err != nil {
		return fmt.Errorf("cannot create mongo database directory: %v", err)
	}

	certKey := info.Cert + "\n" + info.PrivateKey
	err := utils.AtomicWriteFile(sslKeyPath(dataDir), []byte(certKey), 0600)
	if err != nil {
		return fmt.Errorf("cannot write SSL key: %v", err)
	}

	err = utils.AtomicWriteFile(sharedSecretPath(dataDir), []byte(info.SharedSecret), 0600)
	if err != nil {
		return fmt.Errorf("cannot write mongod shared secret: %v", err)
	}

	// Disable the default mongodb installed by the mongodb-server package.
	// Only do this if the file doesn't exist already, so users can run
	// their own mongodb server if they wish to.
	if _, err := os.Stat(mongoConfigPath); os.IsNotExist(err) {
		err = utils.AtomicWriteFile(
			mongoConfigPath,
			[]byte("ENABLE_MONGODB=no"),
			0644,
		)
		if err != nil {
			return err
		}
	}

	if err := aptGetInstallMongod(); err != nil {
		return fmt.Errorf("cannot install mongod: %v", err)
	}

	upstartConf, mongoPath, err := upstartService(namespace, dataDir, dbDir, info.StatePort, withHA)
	if err != nil {
		return err
	}
	logVersion(mongoPath)

	if err := upstartServiceStop(&upstartConf.Service); err != nil {
		return fmt.Errorf("failed to stop mongo: %v", err)
	}
	if err := makeJournalDirs(dbDir); err != nil {
		return fmt.Errorf("error creating journal directories: %v", err)
	}
	return upstartConfInstall(upstartConf)
}
func (*format_1_16Suite) TestStatePortParsed(c *gc.C) {
	dataDir := c.MkDir()
	formatPath := filepath.Join(dataDir, legacyFormatFilename)
	err := utils.AtomicWriteFile(formatPath, []byte(legacyFormatFileContents), 0600)
	c.Assert(err, gc.IsNil)
	configPath := filepath.Join(dataDir, agentConfigFilename)
	err = utils.AtomicWriteFile(configPath, []byte(stateMachineConfigData), 0600)
	c.Assert(err, gc.IsNil)
	readConfig, err := ReadConfig(configPath)
	c.Assert(err, gc.IsNil)
	info, available := readConfig.StateServingInfo()
	c.Assert(available, gc.Equals, true)
	c.Assert(info.StatePort, gc.Equals, 37017)
}
Beispiel #4
0
func writeAuthorisedKeys(username string, keys []string) error {
	keyDir := fmt.Sprintf(authKeysDir, username)
	keyDir, err := utils.NormalizePath(keyDir)
	if err != nil {
		return err
	}
	err = os.MkdirAll(keyDir, os.FileMode(0755))
	if err != nil {
		return fmt.Errorf("cannot create ssh key directory: %v", err)
	}
	keyData := strings.Join(keys, "\n") + "\n"

	// Get perms to use on auth keys file
	sshKeyFile := filepath.Join(keyDir, authKeysFile)
	perms := os.FileMode(0644)
	info, err := os.Stat(sshKeyFile)
	if err == nil {
		perms = info.Mode().Perm()
	}

	logger.Debugf("writing authorised keys file %s", sshKeyFile)
	err = utils.AtomicWriteFile(sshKeyFile, []byte(keyData), perms)
	if err != nil {
		return err
	}

	// TODO (wallyworld) - what to do on windows (if anything)
	// TODO(dimitern) - no need to use user.Current() if username
	// is "" - it will use the current user anyway.
	if runtime.GOOS != "windows" {
		// Ensure the resulting authorised keys file has its ownership
		// set to the specified username.
		var u *user.User
		if username == "" {
			u, err = user.Current()
		} else {
			u, err = user.Lookup(username)
		}
		if err != nil {
			return err
		}
		// chown requires ints but user.User has strings for windows.
		uid, err := strconv.Atoi(u.Uid)
		if err != nil {
			return err
		}
		gid, err := strconv.Atoi(u.Gid)
		if err != nil {
			return err
		}
		err = os.Chown(sshKeyFile, uid, gid)
		if err != nil {
			return err
		}
	}
	return nil
}
func (s *format_1_16Suite) TestMissingAttributes(c *gc.C) {
	dataDir := c.MkDir()
	formatPath := filepath.Join(dataDir, legacyFormatFilename)
	err := utils.AtomicWriteFile(formatPath, []byte(legacyFormatFileContents), 0600)
	c.Assert(err, gc.IsNil)
	configPath := filepath.Join(dataDir, agentConfigFilename)
	err = utils.AtomicWriteFile(configPath, []byte(configDataWithoutNewAttributes), 0600)
	c.Assert(err, gc.IsNil)
	readConfig, err := ReadConfig(configPath)
	c.Assert(err, gc.IsNil)
	c.Assert(readConfig.UpgradedToVersion(), gc.Equals, version.MustParse("1.16.0"))
	c.Assert(readConfig.LogDir(), gc.Equals, "/var/log/juju")
	c.Assert(readConfig.DataDir(), gc.Equals, "/var/lib/juju")
	// Test data doesn't include a StateServerKey so StateServingInfo
	// should *not* be available
	_, available := readConfig.StateServingInfo()
	c.Assert(available, gc.Equals, false)
}
func (s *format_1_18Suite) TestStatePortNotParsedWithoutSecret(c *gc.C) {
	dataDir := c.MkDir()
	configPath := filepath.Join(dataDir, agentConfigFilename)
	err := utils.AtomicWriteFile(configPath, []byte(agentConfig1_18NotStateMachine), 0600)
	c.Assert(err, gc.IsNil)
	readConfig, err := ReadConfig(configPath)
	c.Assert(err, gc.IsNil)
	_, available := readConfig.StateServingInfo()
	c.Assert(available, gc.Equals, false)
}
func (*format_1_18Suite) TestReadConfWithExisting1_18ConfigFileContents(c *gc.C) {
	dataDir := c.MkDir()
	configPath := filepath.Join(dataDir, agentConfigFilename)
	err := utils.AtomicWriteFile(configPath, []byte(agentConfig1_18Contents), 0600)
	c.Assert(err, gc.IsNil)

	config, err := ReadConfig(configPath)
	c.Assert(err, gc.IsNil)
	c.Assert(config.UpgradedToVersion(), jc.DeepEquals, version.MustParse("1.17.5.1"))
	c.Assert(config.Jobs(), jc.DeepEquals, []params.MachineJob{params.JobManageEnviron})
}
func (s *format_1_18Suite) TestMissingAttributes(c *gc.C) {
	dataDir := c.MkDir()
	configPath := filepath.Join(dataDir, agentConfigFilename)
	err := utils.AtomicWriteFile(configPath, []byte(configData1_18WithoutUpgradedToVersion), 0600)
	c.Assert(err, gc.IsNil)
	readConfig, err := ReadConfig(configPath)
	c.Assert(err, gc.IsNil)
	c.Assert(readConfig.UpgradedToVersion(), gc.Equals, version.MustParse("1.16.0"))
	c.Assert(readConfig.LogDir(), gc.Equals, "/var/log/juju")
	c.Assert(readConfig.DataDir(), gc.Equals, "/var/lib/juju")
}
Beispiel #9
0
func (c *configInternal) Write() error {
	data, err := c.fileContents()
	if err != nil {
		return err
	}
	// Make sure the config dir gets created.
	configDir := filepath.Dir(c.configFilePath)
	if err := os.MkdirAll(configDir, 0755); err != nil {
		return fmt.Errorf("cannot create agent config dir %q: %v", configDir, err)
	}
	return utils.AtomicWriteFile(c.configFilePath, data, 0600)
}
Beispiel #10
0
func WriteSystemIdentityFile(c Config) error {
	info, ok := c.StateServingInfo()
	if !ok {
		return fmt.Errorf("StateServingInfo not available and we need it")
	}
	// Write non-empty contents to the file, otherwise delete it
	if info.SystemIdentity != "" {
		err := utils.AtomicWriteFile(c.SystemIdentityPath(), []byte(info.SystemIdentity), 0600)
		if err != nil {
			return fmt.Errorf("cannot write system identity: %v", err)
		}
	} else {
		os.Remove(c.SystemIdentityPath())
	}
	return nil
}
Beispiel #11
0
	err = utils.CopyFile(dest, f.Name())
	c.Assert(err, gc.IsNil)
	data, err := ioutil.ReadFile(dest)
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, "hello world")
}

var atomicWriteFileTests = []struct {
	summary   string
	change    func(filename string, contents []byte) error
	check     func(c *gc.C, fileInfo os.FileInfo)
	expectErr string
}{{
	summary: "atomic file write and chmod 0644",
	change: func(filename string, contents []byte) error {
		return utils.AtomicWriteFile(filename, contents, 0765)
	},
	check: func(c *gc.C, fi os.FileInfo) {
		c.Assert(fi.Mode(), gc.Equals, 0765)
	},
}, {
	summary: "atomic file write and change",
	change: func(filename string, contents []byte) error {
		chmodChange := func(f *os.File) error {
			return f.Chmod(0700)
		}
		return utils.AtomicWriteFileAndChange(filename, contents, chmodChange)
	},
	check: func(c *gc.C, fi os.FileInfo) {
		c.Assert(fi.Mode(), gc.Equals, 0700)
	},