func (s *migrateLocalProviderAgentConfigSuite) assertConfigNotProcessed(c *gc.C) { envConfig, err := s.State.EnvironConfig() c.Assert(err, gc.IsNil) allAttrs := envConfig.AllAttrs() namespace, _ := allAttrs["namespace"].(string) c.Assert(namespace, gc.Equals, "") container, _ := allAttrs["container"].(string) c.Assert(container, gc.Equals, "") rootDir, _ := allAttrs["root-dir"].(string) expectedSharedStorageDir := filepath.Join(rootDir, "shared-storage") _, err = os.Lstat(expectedSharedStorageDir) c.Assert(err, gc.IsNil) tag := s.ctx.AgentConfig().Tag() // We need to read the actual migrated agent config. configFilePath := agent.ConfigPath(agent.DefaultDataDir, tag) agentConfig, err := agent.ReadConfig(configFilePath) c.Assert(err, gc.IsNil) c.Assert(agentConfig.DataDir(), gc.Equals, agent.DefaultDataDir) c.Assert(agentConfig.LogDir(), gc.Equals, agent.DefaultLogDir) c.Assert(agentConfig.Jobs(), gc.HasLen, 0) c.Assert(agentConfig.Value("SHARED_STORAGE_ADDR"), gc.Equals, "blah") c.Assert(agentConfig.Value("SHARED_STORAGE_DIR"), gc.Equals, expectedSharedStorageDir) c.Assert(agentConfig.Value(agent.Namespace), gc.Equals, "") c.Assert(agentConfig.Value(agent.AgentServiceName), gc.Equals, "") c.Assert(agentConfig.Value(agent.ContainerType), gc.Equals, "") }
func (s *UpgradeSuite) assertUpgradeSteps(c *gc.C, job state.MachineJob) { s.PatchValue(&version.Current, s.upgradeToVersion) err := s.State.SetEnvironAgentVersion(s.upgradeToVersion.Number) c.Assert(err, gc.IsNil) oldVersion := s.upgradeToVersion oldVersion.Major = 1 oldVersion.Minor = 16 var oldConfig agent.Config s.machine, oldConfig, _ = s.primeAgent(c, oldVersion, job) a := s.newAgent(c, s.machine) go func() { c.Check(a.Run(nil), gc.IsNil) }() defer func() { c.Check(a.Stop(), gc.IsNil) }() // Wait for upgrade steps to run. success := false for attempt := coretesting.LongAttempt.Start(); attempt.Next(); { conf, err := agent.ReadConfig(agent.ConfigPath(oldConfig.DataDir(), s.machine.Tag())) c.Assert(err, gc.IsNil) success = conf.UpgradedToVersion() == s.upgradeToVersion.Number if success { break } } // Upgrade worker has completed ok. c.Assert(success, jc.IsTrue) }
func (s *migrateLocalProviderAgentConfigSuite) assertConfigProcessed(c *gc.C) { envConfig, err := s.State.EnvironConfig() c.Assert(err, gc.IsNil) allAttrs := envConfig.AllAttrs() namespace, _ := allAttrs["namespace"].(string) c.Assert(namespace, gc.Equals, "user-dummyenv") container, _ := allAttrs["container"].(string) c.Assert(container, gc.Equals, "lxc") expectedDataDir, _ := allAttrs["root-dir"].(string) expectedSharedStorageDir := filepath.Join(expectedDataDir, "shared-storage") _, err = os.Lstat(expectedSharedStorageDir) c.Assert(err, gc.NotNil) c.Assert(err, jc.Satisfies, os.IsNotExist) expectedLogDir := filepath.Join(*upgrades.RootLogDir, "juju-"+namespace) expectedJobs := []params.MachineJob{params.JobManageEnviron} tag := s.ctx.AgentConfig().Tag() // We need to read the actual migrated agent config. configFilePath := agent.ConfigPath(expectedDataDir, tag) agentConfig, err := agent.ReadConfig(configFilePath) c.Assert(err, gc.IsNil) c.Assert(agentConfig.DataDir(), gc.Equals, expectedDataDir) c.Assert(agentConfig.LogDir(), gc.Equals, expectedLogDir) c.Assert(agentConfig.Jobs(), gc.DeepEquals, expectedJobs) c.Assert(agentConfig.Value("SHARED_STORAGE_ADDR"), gc.Equals, "") c.Assert(agentConfig.Value("SHARED_STORAGE_DIR"), gc.Equals, "") c.Assert(agentConfig.Value(agent.Namespace), gc.Equals, namespace) agentService := "juju-agent-user-dummyenv" c.Assert(agentConfig.Value(agent.AgentServiceName), gc.Equals, agentService) c.Assert(agentConfig.Value(agent.ContainerType), gc.Equals, "") }
func (s *agentSuite) testOpenAPIState(c *gc.C, ent state.AgentEntity, agentCmd Agent, initialPassword string) { conf, err := agent.ReadConfig(agent.ConfigPath(s.DataDir(), ent.Tag())) c.Assert(err, gc.IsNil) conf.SetPassword("") err = conf.Write() c.Assert(err, gc.IsNil) // Check that it starts initially and changes the password assertOpen := func(conf agent.Config) { st, gotEnt, err := openAPIState(conf, agentCmd) c.Assert(err, gc.IsNil) c.Assert(st, gc.NotNil) st.Close() c.Assert(gotEnt.Tag(), gc.Equals, ent.Tag()) } assertOpen(conf) // Check that the initial password is no longer valid. err = ent.Refresh() c.Assert(err, gc.IsNil) c.Assert(ent.PasswordValid(initialPassword), gc.Equals, false) // Read the configuration and check that we can connect with it. conf = refreshConfig(c, conf) // Check we can open the API with the new configuration. assertOpen(conf) }
func (s *agentSuite) assertCanOpenState(c *gc.C, tag, dataDir string) { config, err := agent.ReadConfig(agent.ConfigPath(dataDir, tag)) c.Assert(err, gc.IsNil) info, ok := config.StateInfo() c.Assert(ok, jc.IsTrue) st, err := state.Open(info, state.DialOpts{}, environs.NewStatePolicy()) c.Assert(err, gc.IsNil) st.Close() }
func (c *AgentConf) ReadConfig(tag string) error { c.mu.Lock() defer c.mu.Unlock() conf, err := agent.ReadConfig(agent.ConfigPath(c.dataDir, tag)) if err != nil { return err } c._config = conf return nil }
func (*suite) TestWriteAndRead(c *gc.C) { testParams := attributeParams testParams.DataDir = c.MkDir() testParams.LogDir = c.MkDir() conf, err := agent.NewAgentConfig(testParams) c.Assert(err, gc.IsNil) c.Assert(conf.Write(), gc.IsNil) reread, err := agent.ReadConfig(agent.ConfigPath(conf.DataDir(), conf.Tag())) c.Assert(err, gc.IsNil) c.Assert(reread, jc.DeepEquals, conf) }
func (s *BootstrapSuite) TestInitialPassword(c *gc.C) { machineConf, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.envcfg, "--instance-id", string(s.instanceId)) c.Assert(err, gc.IsNil) err = cmd.Run(nil) c.Assert(err, gc.IsNil) // Check that we cannot now connect to the state without a // password. info := &state.Info{ Addrs: []string{testing.MgoServer.Addr()}, CACert: testing.CACert, } testOpenState(c, info, errors.Unauthorizedf("")) // Check we can log in to mongo as admin. info.Tag, info.Password = "", testPasswordHash() st, err := state.Open(info, state.DefaultDialOpts(), environs.NewStatePolicy()) c.Assert(err, gc.IsNil) // Reset password so the tests can continue to use the same server. defer st.Close() defer st.SetAdminMongoPassword("") // Check that the admin user has been given an appropriate // password u, err := st.User("admin") c.Assert(err, gc.IsNil) c.Assert(u.PasswordValid(testPassword), gc.Equals, true) // Check that the machine configuration has been given a new // password and that we can connect to mongo as that machine // and that the in-mongo password also verifies correctly. machineConf1, err := agent.ReadConfig(agent.ConfigPath(machineConf.DataDir(), "machine-0")) c.Assert(err, gc.IsNil) stateinfo, ok := machineConf1.StateInfo() c.Assert(ok, jc.IsTrue) st, err = state.Open(stateinfo, state.DialOpts{}, environs.NewStatePolicy()) c.Assert(err, gc.IsNil) defer st.Close() m, err := st.Machine("0") c.Assert(err, gc.IsNil) c.Assert(m.HasVote(), jc.IsTrue) }
func (fix *SimpleToolsFixture) checkUnitInstalled(c *gc.C, name, password string) { tag := names.UnitTag(name) uconfPath, _, toolsDir := fix.paths(tag) uconfData, err := ioutil.ReadFile(uconfPath) c.Assert(err, gc.IsNil) uconf := string(uconfData) var execLine string for _, line := range strings.Split(uconf, "\n") { if strings.HasPrefix(line, "exec ") { execLine = line break } } if execLine == "" { c.Fatalf("no command found in %s:\n%s", uconfPath, uconf) } logPath := filepath.Join(fix.logDir, tag+".log") jujudPath := filepath.Join(toolsDir, "jujud") for _, pat := range []string{ "^exec " + jujudPath + " unit ", " --unit-name " + name + " ", " >> " + logPath + " 2>&1$", } { match, err := regexp.MatchString(pat, execLine) c.Assert(err, gc.IsNil) if !match { c.Fatalf("failed to match:\n%s\nin:\n%s", pat, execLine) } } conf, err := agent.ReadConfig(agent.ConfigPath(fix.dataDir, tag)) c.Assert(err, gc.IsNil) c.Assert(conf.Tag(), gc.Equals, tag) c.Assert(conf.DataDir(), gc.Equals, fix.dataDir) jujudData, err := ioutil.ReadFile(jujudPath) c.Assert(err, gc.IsNil) c.Assert(string(jujudData), gc.Equals, fakeJujud) }
func (s *bootstrapSuite) TestInitializeState(c *gc.C) { dataDir := c.MkDir() pwHash := utils.UserPasswordHash(testing.DefaultMongoPassword, utils.CompatSalt) configParams := agent.AgentConfigParams{ DataDir: dataDir, Tag: "machine-0", UpgradedToVersion: version.Current.Number, StateAddresses: []string{testing.MgoServer.Addr()}, CACert: testing.CACert, Password: pwHash, } servingInfo := params.StateServingInfo{ Cert: testing.ServerCert, PrivateKey: testing.ServerKey, APIPort: 1234, StatePort: testing.MgoServer.Port(), SystemIdentity: "def456", } cfg, err := agent.NewStateMachineConfig(configParams, servingInfo) c.Assert(err, gc.IsNil) _, available := cfg.StateServingInfo() c.Assert(available, gc.Equals, true) expectConstraints := constraints.MustParse("mem=1024M") expectHW := instance.MustParseHardware("mem=2048M") mcfg := agent.BootstrapMachineConfig{ Addresses: instance.NewAddresses("0.1.2.3", "zeroonetwothree"), Constraints: expectConstraints, Jobs: []params.MachineJob{params.JobHostUnits}, InstanceId: "i-bootstrap", Characteristics: expectHW, SharedSecret: "abc123", } envAttrs := dummy.SampleConfig().Delete("admin-secret").Merge(testing.Attrs{ "agent-version": version.Current.Number.String(), "state-id": "1", // needed so policy can Open config }) envCfg, err := config.New(config.NoDefaults, envAttrs) c.Assert(err, gc.IsNil) st, m, err := agent.InitializeState(cfg, envCfg, mcfg, state.DialOpts{}, environs.NewStatePolicy()) c.Assert(err, gc.IsNil) defer st.Close() err = cfg.Write() c.Assert(err, gc.IsNil) // Check that initial admin user has been set up correctly. s.assertCanLogInAsAdmin(c, pwHash) user, err := st.User("admin") c.Assert(err, gc.IsNil) c.Assert(user.PasswordValid(testing.DefaultMongoPassword), jc.IsTrue) // Check that environment configuration has been added. newEnvCfg, err := st.EnvironConfig() c.Assert(err, gc.IsNil) c.Assert(newEnvCfg.AllAttrs(), gc.DeepEquals, envCfg.AllAttrs()) // Check that the bootstrap machine looks correct. c.Assert(m.Id(), gc.Equals, "0") c.Assert(m.Jobs(), gc.DeepEquals, []state.MachineJob{state.JobHostUnits}) c.Assert(m.Series(), gc.Equals, version.Current.Series) c.Assert(m.CheckProvisioned(state.BootstrapNonce), jc.IsTrue) c.Assert(m.Addresses(), gc.DeepEquals, mcfg.Addresses) gotConstraints, err := m.Constraints() c.Assert(err, gc.IsNil) c.Assert(gotConstraints, gc.DeepEquals, expectConstraints) c.Assert(err, gc.IsNil) gotHW, err := m.HardwareCharacteristics() c.Assert(err, gc.IsNil) c.Assert(*gotHW, gc.DeepEquals, expectHW) gotAddrs := m.Addresses() c.Assert(gotAddrs, gc.DeepEquals, mcfg.Addresses) // Check that the API host ports are initialised correctly. apiHostPorts, err := st.APIHostPorts() c.Assert(err, gc.IsNil) c.Assert(apiHostPorts, gc.DeepEquals, [][]instance.HostPort{ instance.AddressesWithPort(mcfg.Addresses, 1234), }) // Check that the state serving info is initialised correctly. stateServingInfo, err := st.StateServingInfo() c.Assert(err, gc.IsNil) c.Assert(stateServingInfo, jc.DeepEquals, params.StateServingInfo{ APIPort: 1234, StatePort: testing.MgoServer.Port(), Cert: testing.ServerCert, PrivateKey: testing.ServerKey, SharedSecret: "abc123", SystemIdentity: "def456", }) // Check that the machine agent's config has been written // and that we can use it to connect to the state. newCfg, err := agent.ReadConfig(agent.ConfigPath(dataDir, "machine-0")) c.Assert(err, gc.IsNil) c.Assert(newCfg.Tag(), gc.Equals, "machine-0") c.Assert(agent.Password(newCfg), gc.Not(gc.Equals), pwHash) c.Assert(agent.Password(newCfg), gc.Not(gc.Equals), testing.DefaultMongoPassword) info, ok := cfg.StateInfo() c.Assert(ok, jc.IsTrue) st1, err := state.Open(info, state.DialOpts{}, environs.NewStatePolicy()) c.Assert(err, gc.IsNil) defer st1.Close() }
func refreshConfig(c *gc.C, config agent.Config) agent.ConfigSetterWriter { config1, err := agent.ReadConfig(agent.ConfigPath(config.DataDir(), config.Tag())) c.Assert(err, gc.IsNil) return config1 }
func (s *agentSuite) assertCannotOpenState(c *gc.C, tag, dataDir string) { config, err := agent.ReadConfig(agent.ConfigPath(dataDir, tag)) c.Assert(err, gc.IsNil) _, ok := config.StateInfo() c.Assert(ok, jc.IsFalse) }
func (*suite) TestMigrate(c *gc.C) { initialParams := agent.AgentConfigParams{ DataDir: c.MkDir(), LogDir: c.MkDir(), Tag: "omg", Nonce: "nonce", Password: "******", UpgradedToVersion: version.MustParse("1.16.5"), Jobs: []params.MachineJob{ params.JobManageEnviron, params.JobHostUnits, }, CACert: "ca cert", StateAddresses: []string{"localhost:1234"}, APIAddresses: []string{"localhost:4321"}, Values: map[string]string{ "key1": "value1", "key2": "value2", "key3": "value3", }, } migrateTests := []struct { comment string fields []string newParams agent.MigrateParams expectValues map[string]string expectErr string }{{ comment: "nothing to change", fields: nil, newParams: agent.MigrateParams{}, }, { fields: []string{"DataDir"}, newParams: agent.MigrateParams{ DataDir: c.MkDir(), }, }, { fields: []string{"DataDir", "LogDir"}, newParams: agent.MigrateParams{ DataDir: c.MkDir(), LogDir: c.MkDir(), }, }, { fields: []string{"Jobs"}, newParams: agent.MigrateParams{ Jobs: []params.MachineJob{params.JobHostUnits}, }, }, { comment: "invalid/immutable field specified", fields: []string{"InvalidField"}, newParams: agent.MigrateParams{}, expectErr: `unknown field "InvalidField"`, }, { comment: "Values can be added, changed or removed", fields: []string{"Values", "DeleteValues"}, newParams: agent.MigrateParams{ DeleteValues: []string{"key2", "key3"}, // delete Values: map[string]string{ "key1": "new value1", // change "new key3": "value3", // add "empty": "", // add empty val }, }, expectValues: map[string]string{ "key1": "new value1", "new key3": "value3", "empty": "", }, }} for i, test := range migrateTests { summary := "migrate fields" if test.comment != "" { summary += " (" + test.comment + ") " } c.Logf("test %d: %s %v", i, summary, test.fields) initialConfig, err := agent.NewAgentConfig(initialParams) c.Assert(err, gc.IsNil) newConfig, err := agent.NewAgentConfig(initialParams) c.Assert(err, gc.IsNil) c.Assert(initialConfig.Write(), gc.IsNil) c.Assert(agent.ConfigFileExists(initialConfig), jc.IsTrue) err = newConfig.Migrate(test.newParams) c.Assert(err, gc.IsNil) err = newConfig.Write() c.Assert(err, gc.IsNil) c.Assert(agent.ConfigFileExists(newConfig), jc.IsTrue) // Make sure we can read it back successfully and it // matches what we wrote. configPath := agent.ConfigPath(newConfig.DataDir(), newConfig.Tag()) readConfig, err := agent.ReadConfig(configPath) c.Check(err, gc.IsNil) c.Check(newConfig, jc.DeepEquals, readConfig) // Make sure only the specified fields were changed and // the rest matches. for _, field := range test.fields { switch field { case "Values": err = agent.PatchConfig(initialConfig, field, test.expectValues) c.Check(err, gc.IsNil) case "DeleteValues": err = agent.PatchConfig(initialConfig, field, test.newParams.DeleteValues) c.Check(err, gc.IsNil) default: value := reflect.ValueOf(test.newParams).FieldByName(field) if value.IsValid() && test.expectErr == "" { err = agent.PatchConfig(initialConfig, field, value.Interface()) c.Check(err, gc.IsNil) } else { err = agent.PatchConfig(initialConfig, field, value) c.Check(err, gc.ErrorMatches, test.expectErr) } } } c.Check(newConfig, jc.DeepEquals, initialConfig) } }