func (*suite) TestStateServingInfoNotAvailable(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, gc.IsNil) _, available := conf.StateServingInfo() c.Assert(available, gc.Equals, false) }
// primeAgent writes the configuration file and tools with version vers // for an agent with the given entity name. It returns the agent's // configuration and the current tools. func (s *agentSuite) primeAgent(c *gc.C, tag, password string, vers version.Binary) (agent.ConfigSetterWriter, *coretools.Tools) { stor := s.Conn.Environ.Storage() agentTools := envtesting.PrimeTools(c, stor, s.DataDir(), vers) err := envtools.MergeAndWriteMetadata(stor, coretools.List{agentTools}, envtools.DoNotWriteMirrors) c.Assert(err, gc.IsNil) tools1, err := agenttools.ChangeAgentTools(s.DataDir(), tag, vers) c.Assert(err, gc.IsNil) c.Assert(tools1, gc.DeepEquals, agentTools) stateInfo := s.StateInfo(c) apiInfo := s.APIInfo(c) conf, err := agent.NewAgentConfig( agent.AgentConfigParams{ DataDir: s.DataDir(), Tag: tag, UpgradedToVersion: vers.Number, Password: password, Nonce: state.BootstrapNonce, StateAddresses: stateInfo.Addrs, APIAddresses: apiInfo.Addrs, CACert: stateInfo.CACert, }) conf.SetPassword(password) c.Assert(conf.Write(), gc.IsNil) s.primeAPIHostPorts(c) return conf, agentTools }
func (cfg *MachineConfig) agentConfig(tag string) (agent.ConfigSetter, error) { // TODO for HAState: the stateHostAddrs and apiHostAddrs here assume that // if the machine is a stateServer then to use localhost. This may be // sufficient, but needs thought in the new world order. var password string if cfg.StateInfo == nil { password = cfg.APIInfo.Password } else { password = cfg.StateInfo.Password } configParams := agent.AgentConfigParams{ DataDir: cfg.DataDir, LogDir: cfg.LogDir, Jobs: cfg.Jobs, Tag: tag, UpgradedToVersion: version.Current.Number, Password: password, Nonce: cfg.MachineNonce, StateAddresses: cfg.stateHostAddrs(), APIAddresses: cfg.apiHostAddrs(), CACert: cfg.StateInfo.CACert, Values: cfg.AgentEnvironment, } if !cfg.Bootstrap { return agent.NewAgentConfig(configParams) } return agent.NewStateMachineConfig(configParams, *cfg.StateServingInfo) }
func (*suite) TestSetAPIHostPorts(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, gc.IsNil) addrs, err := conf.APIAddresses() c.Assert(err, gc.IsNil) c.Assert(addrs, gc.DeepEquals, attributeParams.APIAddresses) // The first cloud-local address for each server is used, // else if there are none then the first public- or unknown- // scope address. // // If a server has only machine-local addresses, or none // at all, then it will be excluded. server1 := instance.NewAddresses("0.1.2.3", "0.1.2.4", "zeroonetwothree") server1[0].NetworkScope = instance.NetworkCloudLocal server1[1].NetworkScope = instance.NetworkCloudLocal server1[2].NetworkScope = instance.NetworkPublic server2 := instance.NewAddresses("127.0.0.1") server2[0].NetworkScope = instance.NetworkMachineLocal server3 := instance.NewAddresses("0.1.2.5", "zeroonetwofive") server3[0].NetworkScope = instance.NetworkUnknown server3[1].NetworkScope = instance.NetworkUnknown conf.SetAPIHostPorts([][]instance.HostPort{ instance.AddressesWithPort(server1, 123), instance.AddressesWithPort(server2, 124), instance.AddressesWithPort(server3, 125), }) addrs, err = conf.APIAddresses() c.Assert(err, gc.IsNil) c.Assert(addrs, gc.DeepEquals, []string{"0.1.2.3:123", "0.1.2.5:125"}) }
func (*suite) TestSetOldPassword(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, gc.IsNil) c.Assert(conf.OldPassword(), gc.Equals, attributeParams.Password) conf.SetOldPassword("newoldpassword") c.Assert(conf.OldPassword(), gc.Equals, "newoldpassword") }
func (*suite) TestSetUpgradedToVersion(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, gc.IsNil) c.Assert(conf.UpgradedToVersion(), gc.Equals, version.Current.Number) expectVers := version.MustParse("3.4.5") conf.SetUpgradedToVersion(expectVers) c.Assert(conf.UpgradedToVersion(), gc.Equals, expectVers) }
func (*suite) TestAttributes(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, gc.IsNil) c.Assert(conf.DataDir(), gc.Equals, "/data/dir") c.Assert(conf.SystemIdentityPath(), gc.Equals, "/data/dir/system-identity") c.Assert(conf.Tag(), gc.Equals, "omg") c.Assert(conf.Dir(), gc.Equals, "/data/dir/agents/omg") c.Assert(conf.Nonce(), gc.Equals, "a nonce") c.Assert(conf.UpgradedToVersion(), jc.DeepEquals, version.Current.Number) }
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 *suite) TestAPIAddressesCannotWriteBack(c *gc.C) { conf, err := agent.NewAgentConfig(attributeParams) c.Assert(err, gc.IsNil) value, err := conf.APIAddresses() c.Assert(err, gc.IsNil) c.Assert(value, jc.DeepEquals, []string{"localhost:1235"}) value[0] = "invalidAdr" //Check out change hasn't gone back into the internals newValue, err := conf.APIAddresses() c.Assert(err, gc.IsNil) c.Assert(newValue, jc.DeepEquals, []string{"localhost:1235"}) }
func (*suite) TestNewAgentConfig(c *gc.C) { for i, test := range agentConfigTests { c.Logf("%v: %s", i, test.about) _, err := agent.NewAgentConfig(test.params) if test.checkErr == "" { c.Assert(err, gc.IsNil) } else { c.Assert(err, gc.ErrorMatches, test.checkErr) } } }
func (s *bootstrapSuite) TestInitializeStateFailsSecondTime(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, } cfg, err := agent.NewAgentConfig(configParams) c.Assert(err, gc.IsNil) cfg.SetStateServingInfo(params.StateServingInfo{ APIPort: 5555, StatePort: testing.MgoServer.Port(), Cert: "foo", PrivateKey: "bar", SharedSecret: "baz", SystemIdentity: "qux", }) expectConstraints := constraints.MustParse("mem=1024M") expectHW := instance.MustParseHardware("mem=2048M") mcfg := agent.BootstrapMachineConfig{ Constraints: expectConstraints, Jobs: []params.MachineJob{params.JobHostUnits}, InstanceId: "i-bootstrap", Characteristics: expectHW, } 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, _, err := agent.InitializeState(cfg, envCfg, mcfg, state.DialOpts{}, environs.NewStatePolicy()) c.Assert(err, gc.IsNil) err = st.SetAdminMongoPassword("") c.Check(err, gc.IsNil) st.Close() st, _, err = agent.InitializeState(cfg, envCfg, mcfg, state.DialOpts{}, environs.NewStatePolicy()) if err == nil { st.Close() } c.Assert(err, gc.ErrorMatches, "failed to initialize state: cannot create log collection: unauthorized mongo access: unauthorized") }
func (s *JujuConnSuite) AgentConfigForTag(c *gc.C, tag string) agent.Config { password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) config, err := agent.NewAgentConfig( agent.AgentConfigParams{ DataDir: s.DataDir(), Tag: tag, UpgradedToVersion: version.Current.Number, Password: password, Nonce: "nonce", StateAddresses: s.StateInfo(c).Addrs, APIAddresses: s.APIInfo(c).Addrs, CACert: testing.CACert, }) c.Assert(err, gc.IsNil) return config }
func (s *bootstrapSuite) TestInitializeStateWithStateServingInfoNotAvailable(c *gc.C) { configParams := agent.AgentConfigParams{ DataDir: c.MkDir(), Tag: "machine-0", UpgradedToVersion: version.Current.Number, StateAddresses: []string{testing.MgoServer.Addr()}, CACert: testing.CACert, Password: "******", } cfg, err := agent.NewAgentConfig(configParams) c.Assert(err, gc.IsNil) _, available := cfg.StateServingInfo() c.Assert(available, gc.Equals, false) _, _, err = agent.InitializeState(cfg, nil, agent.BootstrapMachineConfig{}, state.DialOpts{}, environs.NewStatePolicy()) // InitializeState will fail attempting to get the api port information c.Assert(err, gc.ErrorMatches, "state serving information not available") }
func (s *lxcBrokerSuite) SetUpTest(c *gc.C) { s.lxcSuite.SetUpTest(c) tools := &coretools.Tools{ Version: version.MustParseBinary("2.3.4-foo-bar"), URL: "http://tools.testing.invalid/2.3.4-foo-bar.tgz", } var err error s.agentConfig, err = agent.NewAgentConfig( agent.AgentConfigParams{ DataDir: "/not/used/here", Tag: "tag", UpgradedToVersion: version.Current.Number, Password: "******", Nonce: "nonce", APIAddresses: []string{"10.0.0.1:1234"}, CACert: coretesting.CACert, }) c.Assert(err, gc.IsNil) managerConfig := container.ManagerConfig{container.ConfigName: "juju"} s.broker, err = provisioner.NewLxcBroker(&fakeAPI{}, tools, s.agentConfig, managerConfig) c.Assert(err, gc.IsNil) }
func (s *migrateLocalProviderAgentConfigSuite) primeConfig(c *gc.C, st *state.State, job state.MachineJob, tag string) { rootDir := c.MkDir() sharedStorageDir := filepath.Join(rootDir, "shared-storage") c.Assert(os.MkdirAll(sharedStorageDir, 0755), gc.IsNil) localLogDir := filepath.Join(rootDir, "log") c.Assert(os.MkdirAll(localLogDir, 0755), gc.IsNil) initialConfig, err := agent.NewAgentConfig(agent.AgentConfigParams{ Tag: tag, Password: "******", CACert: testing.CACert, StateAddresses: []string{"localhost:1111"}, DataDir: agent.DefaultDataDir, LogDir: agent.DefaultLogDir, UpgradedToVersion: version.MustParse("1.16.0"), Values: map[string]string{ "SHARED_STORAGE_ADDR": "blah", "SHARED_STORAGE_DIR": sharedStorageDir, }, }) c.Assert(err, gc.IsNil) s.config = initialConfig c.Assert(s.config.Write(), gc.IsNil) apiState, _ := s.OpenAPIAsNewMachine(c, job) s.ctx = &mockContext{ realAgentConfig: initialConfig, apiState: apiState, state: st, } newCfg := (map[string]interface{}{ "root-dir": rootDir, }) err = s.State.UpdateEnvironConfig(newCfg, nil, nil) c.Assert(err, gc.IsNil) }
func (ctx *SimpleContext) DeployUnit(unitName, initialPassword string) (err error) { // Check sanity. svc := ctx.upstartService(unitName) if svc.Installed() { return fmt.Errorf("unit %q is already deployed", unitName) } // Link the current tools for use by the new agent. tag := names.UnitTag(unitName) dataDir := ctx.agentConfig.DataDir() logDir := ctx.agentConfig.LogDir() _, err = tools.ChangeAgentTools(dataDir, tag, version.Current) toolsDir := tools.ToolsDir(dataDir, tag) defer removeOnErr(&err, toolsDir) result, err := ctx.api.ConnectionInfo() if err != nil { return err } logger.Debugf("state addresses: %q", result.StateAddresses) logger.Debugf("API addresses: %q", result.APIAddresses) containerType := ctx.agentConfig.Value(agent.ContainerType) namespace := ctx.agentConfig.Value(agent.Namespace) conf, err := agent.NewAgentConfig( agent.AgentConfigParams{ DataDir: dataDir, LogDir: logDir, UpgradedToVersion: version.Current.Number, Tag: tag, Password: initialPassword, Nonce: "unused", // TODO: remove the state addresses here and test when api only. StateAddresses: result.StateAddresses, APIAddresses: result.APIAddresses, CACert: ctx.agentConfig.CACert(), Values: map[string]string{ agent.ContainerType: containerType, agent.Namespace: namespace, }, }) if err != nil { return err } if err := conf.Write(); err != nil { return err } defer removeOnErr(&err, conf.Dir()) // Install an upstart job that runs the unit agent. logPath := path.Join(logDir, tag+".log") cmd := strings.Join([]string{ path.Join(toolsDir, "jujud"), "unit", "--data-dir", dataDir, "--unit-name", unitName, "--debug", // TODO: propagate debug state sensibly }, " ") // TODO(thumper): 2013-09-02 bug 1219630 // As much as I'd like to remove JujuContainerType now, it is still // needed as MAAS still needs it at this stage, and we can't fix // everything at once. uconf := &upstart.Conf{ Service: *svc, Desc: "juju unit agent for " + unitName, Cmd: cmd, Out: logPath, Env: map[string]string{ osenv.JujuContainerTypeEnvKey: containerType, }, } return uconf.Install() }
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) } }