func (s *BootstrapSuite) TestDefaultStoragePools(c *gc.C) { _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPassword, }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() settings := state.NewStateSettings(st) pm := poolmanager.New(settings) for _, p := range []string{"ebs-ssd"} { _, err = pm.Get(p) c.Assert(err, jc.ErrorIsNil) } }
// Run resolves c.Target to a machine, to the address of a i // machine or unit forks ssh passing any arguments provided. func (c *SSHCommand) Run(ctx *cmd.Context) error { if c.apiClient == nil { // If the apClient is not already opened and it is opened // by ensureAPIClient, then close it when we're done. defer func() { if c.apiClient != nil { c.apiClient.Close() c.apiClient = nil } }() } options, err := c.getSSHOptions(c.pty) if err != nil { return err } host, err := c.hostFromTarget(c.Target) if err != nil { return err } cmd := ssh.Command("ubuntu@"+host, c.Args, options) cmd.Stdin = ctx.Stdin cmd.Stdout = ctx.Stdout cmd.Stderr = ctx.Stderr return cmd.Run() }
func (s *BootstrapSuite) TestSetConstraints(c *gc.C) { tcons := constraints.Value{Mem: uint64p(2048), CpuCores: uint64p(2)} _, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--constraints", tcons.String(), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) st, err := state.Open(testing.EnvironmentTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPasswordHash(), }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() cons, err := st.EnvironConstraints() c.Assert(err, jc.ErrorIsNil) c.Assert(cons, gc.DeepEquals, tcons) machines, err := st.AllMachines() c.Assert(err, jc.ErrorIsNil) c.Assert(machines, gc.HasLen, 1) cons, err = machines[0].Constraints() c.Assert(err, jc.ErrorIsNil) c.Assert(cons, gc.DeepEquals, tcons) }
func (s *BootstrapSuite) TestInitializeEnvironmentToolsNotFound(c *gc.C) { // bootstrap with 1.99.1 but there will be no tools so version will be reset. envcfg, err := s.envcfg.Apply(map[string]interface{}{ "agent-version": "1.99.1", }) c.Assert(err, jc.ErrorIsNil) b64yamlControllerModelConfig := b64yaml(envcfg.AllAttrs()).encode() hw := instance.MustParseHardware("arch=amd64 mem=8G") _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), "--hardware", hw.String(), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPassword, }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() cfg, err := st.ModelConfig() c.Assert(err, jc.ErrorIsNil) vers, ok := cfg.AgentVersion() c.Assert(ok, jc.IsTrue) c.Assert(vers.String(), gc.Equals, "1.99.0") }
func (s *LoginCommandSuite) run(c *gc.C, stdin string, args ...string) (*cmd.Context, juju.NewAPIConnectionParams, error) { var argsOut juju.NewAPIConnectionParams cmd, _ := user.NewLoginCommandForTest(func(args juju.NewAPIConnectionParams) (user.LoginAPI, user.ConnectionAPI, error) { argsOut = args // The account details are modified in place, so take a copy. accountDetails := *argsOut.AccountDetails argsOut.AccountDetails = &accountDetails if s.loginErr != nil { err := s.loginErr s.loginErr = nil return nil, nil, err } return s.mockAPI, s.mockAPI, nil }, s.store) ctx := coretesting.Context(c) if stdin == "" { stdin = "sekrit\n" } ctx.Stdin = strings.NewReader(stdin) err := coretesting.InitCommand(cmd, args) if err != nil { return nil, argsOut, err } err = cmd.Run(ctx) return ctx, argsOut, err }
func testEnsureControllerName(c *gc.C, store jujuclient.ClientStore, expect string, args ...string) { cmd, controllerCmd, err := initTestControllerCommand(c, store, args...) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(controllerCmd.ControllerName(), gc.Equals, expect) }
func (s *BootstrapSuite) TestSetConstraints(c *gc.C) { bootstrapCons := constraints.Value{Mem: uint64p(4096), CpuCores: uint64p(4)} modelCons := constraints.Value{Mem: uint64p(2048), CpuCores: uint64p(2)} _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), "--bootstrap-constraints", bootstrapCons.String(), "--constraints", modelCons.String(), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPassword, }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() cons, err := st.ModelConstraints() c.Assert(err, jc.ErrorIsNil) c.Assert(cons, gc.DeepEquals, modelCons) machines, err := st.AllMachines() c.Assert(err, jc.ErrorIsNil) c.Assert(machines, gc.HasLen, 1) cons, err = machines[0].Constraints() c.Assert(err, jc.ErrorIsNil) c.Assert(cons, gc.DeepEquals, bootstrapCons) }
func (c *restoreCommand) runRestore(ctx *cmd.Context) error { cmdArgs := []string{"backups"} if c.Log.Path != "" { cmdArgs = append(cmdArgs, "--log-file", c.Log.Path) } if c.Log.Verbose { cmdArgs = append(cmdArgs, "--verbose") } if c.Log.Quiet { cmdArgs = append(cmdArgs, "--quiet") } if c.Log.Debug { cmdArgs = append(cmdArgs, "--debug") } if c.Log.Config != c.Log.DefaultConfig { cmdArgs = append(cmdArgs, "--logging-config", c.Log.Config) } if c.Log.ShowLog { cmdArgs = append(cmdArgs, "--show-log") } cmdArgs = append(cmdArgs, "restore", "-b", "--file", c.backupFile) cmd := exec.Command("juju", cmdArgs...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() }
func (s *BootstrapSuite) TestDefaultMachineJobs(c *gc.C) { expectedJobs := []state.MachineJob{ state.JobManageModel, state.JobHostUnits, state.JobManageNetworking, } _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPassword, }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() m, err := st.Machine("0") c.Assert(err, jc.ErrorIsNil) c.Assert(m.Jobs(), gc.DeepEquals, expectedJobs) }
func (s *BootstrapSuite) TestInitializeStateMinSocketTimeout(c *gc.C) { var called int initializeState := func(_ names.UserTag, _ agent.ConfigSetter, envCfg *config.Config, hostedModelConfig map[string]interface{}, machineCfg agentbootstrap.BootstrapMachineConfig, dialOpts mongo.DialOpts, policy state.Policy) (_ *state.State, _ *state.Machine, resultErr error) { called++ c.Assert(dialOpts.Direct, jc.IsTrue) c.Assert(dialOpts.SocketTimeout, gc.Equals, 1*time.Minute) return nil, nil, errors.New("failed to initialize state") } envcfg, err := s.envcfg.Apply(map[string]interface{}{ "bootstrap-timeout": "13", }) c.Assert(err, jc.ErrorIsNil) b64yamlControllerModelConfig := b64yaml(envcfg.AllAttrs()).encode() s.PatchValue(&agentInitializeState, initializeState) _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, gc.ErrorMatches, "failed to initialize state") c.Assert(called, gc.Equals, 1) }
func (s *BootstrapSuite) TestCustomDataSourceHasKey(c *gc.C) { dir, _, _ := createImageMetadata(c) _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), "--image-metadata", dir, ) c.Assert(err, jc.ErrorIsNil) called := false s.PatchValue(&storeImageMetadataFromFiles, func(st *state.State, env environs.Environ, source simplestreams.DataSource) error { called = true // This data source does not require to contain signed data. // However, it may still contain it. // Since we will always try to read signed data first, // we want to be able to try to read this signed data // with a user provided public key. For this test, none is provided. // Bugs #1542127, #1542131 c.Assert(source.PublicSigningKey(), gc.Equals, "") return nil }) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(called, jc.IsTrue) }
func (s *BootstrapSuite) testToolsMetadata(c *gc.C, exploded bool) { provider, err := environs.Provider(s.envcfg.Type()) c.Assert(err, gc.IsNil) env, err := provider.Open(s.envcfg) c.Assert(err, gc.IsNil) oldMetadata, err := envtools.ReadMetadata(env.Storage()) c.Assert(err, gc.IsNil) _, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId)) c.Assert(err, gc.IsNil) err = cmd.Run(nil) c.Assert(err, gc.IsNil) newMetadata, err := envtools.ReadMetadata(env.Storage()) c.Assert(err, gc.IsNil) if !exploded { c.Assert(newMetadata, gc.HasLen, len(oldMetadata)) } else { // new metadata should have more tools. c.Assert(len(newMetadata), jc.GreaterThan, len(oldMetadata)) var expectedSeries set.Strings for _, series := range version.SupportedSeries() { os, err := version.GetOSFromSeries(series) c.Assert(err, gc.IsNil) if os == version.Ubuntu { expectedSeries.Add(series) } } c.Assert(newMetadata, gc.HasLen, expectedSeries.Size()) for _, m := range newMetadata { c.Assert(expectedSeries.Contains(m.Release), jc.IsTrue) } } }
func (s *BootstrapSuite) TestGUIArchiveInfoError(c *gc.C) { if runtime.GOOS == "windows" { // TODO frankban: skipping for now due to chmod problems with mode 0000 // on Windows. We will re-enable this test after further investigation: // "jujud bootstrap" is never run on Windows anyway. c.Skip("needs chmod investigation") } dir := filepath.FromSlash(agenttools.SharedGUIDir(s.dataDir)) info := filepath.Join(dir, "downloaded-gui.txt") err := os.Chmod(info, 0000) c.Assert(err, jc.ErrorIsNil) defer os.Chmod(info, 0600) _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId)) c.Assert(err, jc.ErrorIsNil) var tw loggo.TestWriter err = loggo.RegisterWriter("bootstrap-test", &tw, loggo.DEBUG) c.Assert(err, jc.ErrorIsNil) defer loggo.RemoveWriter("bootstrap-test") err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(tw.Log(), jc.LogMatches, jc.SimpleMessages{{ loggo.WARNING, `cannot set up Juju GUI: cannot fetch GUI info: cannot read GUI metadata in tools directory: .*`, }}) }
func (s *BootstrapSuite) TestImageMetadata(c *gc.C) { metadataDir, _, expected := createImageMetadata(c) var stor statetesting.MapStorage s.PatchValue(&newStateStorage, func(string, *mgo.Session) statestorage.Storage { return &stor }) _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), "--image-metadata", metadataDir, ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) // The contents of the directory should have been added to // environment storage. for _, pair := range expected { r, length, err := stor.Get(pair.path) c.Assert(err, jc.ErrorIsNil) data, err := ioutil.ReadAll(r) r.Close() c.Assert(err, jc.ErrorIsNil) c.Assert(length, gc.Equals, int64(len(pair.content))) c.Assert(data, gc.HasLen, int(length)) c.Assert(string(data), gc.Equals, pair.content) } }
func (s *BootstrapSuite) TestInitializeEnvironmentInvalidOplogSize(c *gc.C) { s.mongoOplogSize = "NaN" hw := instance.MustParseHardware("arch=amd64 mem=8G") _, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--hardware", hw.String()) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, gc.ErrorMatches, `invalid oplog size: "NaN"`) }
func (s *BootstrapSuite) TestInitializeEnvironment(c *gc.C) { hw := instance.MustParseHardware("arch=amd64 mem=8G") machConf, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.envcfg, "--instance-id", string(s.instanceId), "--hardware", hw.String()) c.Assert(err, gc.IsNil) err = cmd.Run(nil) c.Assert(err, gc.IsNil) c.Assert(s.fakeEnsureMongo.dataDir, gc.Equals, s.dataDir) c.Assert(s.fakeEnsureMongo.initiateCount, gc.Equals, 1) c.Assert(s.fakeEnsureMongo.ensureCount, gc.Equals, 1) c.Assert(s.fakeEnsureMongo.dataDir, gc.Equals, s.dataDir) c.Assert(s.fakeEnsureMongo.oplogSize, gc.Equals, 1234) expectInfo, exists := machConf.StateServingInfo() c.Assert(exists, jc.IsTrue) c.Assert(expectInfo.SharedSecret, gc.Equals, "") servingInfo := s.fakeEnsureMongo.info c.Assert(len(servingInfo.SharedSecret), gc.Not(gc.Equals), 0) servingInfo.SharedSecret = "" c.Assert(servingInfo, jc.DeepEquals, expectInfo) expectDialAddrs := []string{fmt.Sprintf("127.0.0.1:%d", expectInfo.StatePort)} gotDialAddrs := s.fakeEnsureMongo.initiateParams.DialInfo.Addrs c.Assert(gotDialAddrs, gc.DeepEquals, expectDialAddrs) memberHost := fmt.Sprintf("%s:%d", s.bootstrapName, expectInfo.StatePort) c.Assert(s.fakeEnsureMongo.initiateParams.MemberHostPort, gc.Equals, memberHost) c.Assert(s.fakeEnsureMongo.initiateParams.User, gc.Equals, "") c.Assert(s.fakeEnsureMongo.initiateParams.Password, gc.Equals, "") st, err := state.Open(&authentication.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPasswordHash(), }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) c.Assert(err, gc.IsNil) defer st.Close() machines, err := st.AllMachines() c.Assert(err, gc.IsNil) c.Assert(machines, gc.HasLen, 1) instid, err := machines[0].InstanceId() c.Assert(err, gc.IsNil) c.Assert(instid, gc.Equals, instance.Id(string(s.instanceId))) stateHw, err := machines[0].HardwareCharacteristics() c.Assert(err, gc.IsNil) c.Assert(stateHw, gc.NotNil) c.Assert(*stateHw, gc.DeepEquals, hw) cons, err := st.EnvironConstraints() c.Assert(err, gc.IsNil) c.Assert(&cons, jc.Satisfies, constraints.IsEmpty) }
func (s *BootstrapSuite) TestInitialPassword(c *gc.C) { machineConf, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) info := &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, } // Check we can log in to mongo as admin. // TODO(dfc) does passing nil for the admin user name make your skin crawl ? mine too. info.Tag, info.Password = nil, testPassword st, err := state.Open(testing.ModelTag, info, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() // We're running Mongo with --noauth; let's explicitly verify // that we can login as that user. Even with --noauth, an // explicit Login will still be verified. adminDB := st.MongoSession().DB("admin") err = adminDB.Login("admin", "invalid-password") c.Assert(err, gc.ErrorMatches, "(auth|(.*Authentication)) fail(s|ed)\\.?") err = adminDB.Login("admin", info.Password) c.Assert(err, jc.ErrorIsNil) // Check that the admin user has been given an appropriate // password u, err := st.User(names.NewLocalUserTag("admin")) c.Assert(err, jc.ErrorIsNil) c.Assert(u.PasswordValid(testPassword), jc.IsTrue) // 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(), names.NewMachineTag("0"))) c.Assert(err, jc.ErrorIsNil) stateinfo, ok := machineConf1.MongoInfo() c.Assert(ok, jc.IsTrue) st, err = state.Open(testing.ModelTag, stateinfo, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() m, err := st.Machine("0") c.Assert(err, jc.ErrorIsNil) c.Assert(m.HasVote(), jc.IsTrue) }
// runViaJujuSSH will run arbitrary code in the remote machine. func runViaJujuSSH(machine, script string, stdout, stderr *bytes.Buffer) error { cmd := exec.Command("ssh", []string{"-o StrictHostKeyChecking=no", fmt.Sprintf("ubuntu@%s", machine), "sudo -n bash -c " + utils.ShQuote(script)}...) cmd.Stderr = stderr cmd.Stdout = stdout err := cmd.Run() if err != nil { return errors.Annotatef(err, "ssh command failed: (%q)", stderr.String()) } return nil }
func (s *BootstrapSuite) testToolsMetadata(c *gc.C, exploded bool) { envtesting.RemoveFakeToolsMetadata(c, s.toolsStorage) _, cmd, err := s.initBootstrapCommand(c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) // We don't write metadata at bootstrap anymore. simplestreamsMetadata, err := envtools.ReadMetadata(s.toolsStorage, "released") c.Assert(err, jc.ErrorIsNil) c.Assert(simplestreamsMetadata, gc.HasLen, 0) // The tools should have been added to tools storage, and // exploded into each of the supported series of // the same operating system if the tools were uploaded. st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPassword, }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() expectedSeries := make(set.Strings) if exploded { for _, ser := range series.SupportedSeries() { os, err := series.GetOSFromSeries(ser) c.Assert(err, jc.ErrorIsNil) hostos, err := series.GetOSFromSeries(series.HostSeries()) c.Assert(err, jc.ErrorIsNil) if os == hostos { expectedSeries.Add(ser) } } } else { expectedSeries.Add(series.HostSeries()) } storage, err := st.ToolsStorage() c.Assert(err, jc.ErrorIsNil) defer storage.Close() metadata, err := storage.AllMetadata() c.Assert(err, jc.ErrorIsNil) c.Assert(metadata, gc.HasLen, expectedSeries.Size()) for _, m := range metadata { v := version.MustParseBinary(m.Version) c.Assert(expectedSeries.Contains(v.Series), jc.IsTrue) } }
func (s *BootstrapSuite) testToolsMetadata(c *gc.C, exploded bool) { provider, err := environs.Provider(s.envcfg.Type()) c.Assert(err, gc.IsNil) env, err := provider.Open(s.envcfg) c.Assert(err, gc.IsNil) envtesting.RemoveFakeToolsMetadata(c, env.Storage()) _, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId)) c.Assert(err, gc.IsNil) err = cmd.Run(nil) c.Assert(err, gc.IsNil) // We don't write metadata at bootstrap anymore. simplestreamsMetadata, err := envtools.ReadMetadata(env.Storage()) c.Assert(err, gc.IsNil) c.Assert(simplestreamsMetadata, gc.HasLen, 0) // The tools should have been added to state, and // exploded into each of the supported series of // the same operating system if the tools were uploaded. st, err := state.Open(&mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPasswordHash(), }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) c.Assert(err, gc.IsNil) defer st.Close() var expectedSeries set.Strings if exploded { for _, series := range version.SupportedSeries() { os, err := version.GetOSFromSeries(series) c.Assert(err, gc.IsNil) if os == version.Current.OS { expectedSeries.Add(series) } } } else { expectedSeries.Add(version.Current.Series) } storage, err := st.ToolsStorage() c.Assert(err, gc.IsNil) defer storage.Close() metadata, err := storage.AllMetadata() c.Assert(err, gc.IsNil) c.Assert(metadata, gc.HasLen, expectedSeries.Size()) for _, m := range metadata { c.Assert(expectedSeries.Contains(m.Version.Series), jc.IsTrue) } }
func (s *BootstrapSuite) TestSystemIdentityWritten(c *gc.C) { _, err := os.Stat(filepath.Join(s.dataDir, agent.SystemIdentity)) c.Assert(err, jc.Satisfies, os.IsNotExist) _, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId)) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) data, err := ioutil.ReadFile(filepath.Join(s.dataDir, agent.SystemIdentity)) c.Assert(err, jc.ErrorIsNil) c.Assert(string(data), gc.Equals, "private-key") }
func (s *BootstrapSuite) TestStructuredImageMetadataStored(c *gc.C) { dir, m := createImageMetadata(c) _, cmd, err := s.initBootstrapCommand( c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--image-metadata", dir, ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) // This metadata should have also been written to state... assertWrittenToState(c, m) }
func runViaSsh(addr string, script string) error { // This is taken from cmd/juju/ssh.go there is no other clear way to set user userAddr := "ubuntu@" + addr cmd := ssh.Command(userAddr, []string{"sudo", "-n", "bash", "-c " + utils.ShQuote(script)}, nil) var stderrBuf bytes.Buffer var stdoutBuf bytes.Buffer cmd.Stderr = &stderrBuf cmd.Stdout = &stdoutBuf err := cmd.Run() if err != nil { return fmt.Errorf("ssh command failed: %v (%q)", err, stderrBuf.String()) } progress("ssh command succedded: %q", stdoutBuf.String()) return nil }
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 := &authentication.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, } testOpenState(c, info, errors.Unauthorizedf("")) // Check we can log in to mongo as admin. // TODO(dfc) does passing nil for the admin user name make your skin crawl ? mine too. info.Tag, info.Password = nil, testPasswordHash() st, err := state.Open(info, mongo.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(), names.NewMachineTag("0"))) c.Assert(err, gc.IsNil) stateinfo, ok := machineConf1.MongoInfo() c.Assert(ok, jc.IsTrue) st, err = state.Open(stateinfo, mongo.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 (s *BootstrapSuite) TestInitializeStateArgs(c *gc.C) { var called int initializeState := func(_ names.UserTag, _ agent.ConfigSetter, envCfg *config.Config, machineCfg agent.BootstrapMachineConfig, dialOpts mongo.DialOpts, policy state.Policy) (_ *state.State, _ *state.Machine, resultErr error) { called++ c.Assert(dialOpts.Direct, jc.IsTrue) c.Assert(dialOpts.Timeout, gc.Equals, 30*time.Second) c.Assert(dialOpts.SocketTimeout, gc.Equals, 123*time.Second) return nil, nil, errors.New("failed to initialize state") } s.PatchValue(&agentInitializeState, initializeState) _, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId)) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, gc.ErrorMatches, "failed to initialize state") c.Assert(called, gc.Equals, 1) }
func (s *BootstrapSuite) TestImageMetadata(c *gc.C) { metadataDir := c.MkDir() expected := []struct{ path, content string }{{ path: "images/streams/v1/index.json", content: "abc", }, { path: "images/streams/v1/products.json", content: "def", }, { path: "wayward/file.txt", content: "ghi", }} for _, pair := range expected { path := filepath.Join(metadataDir, pair.path) err := os.MkdirAll(filepath.Dir(path), 0755) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(path, []byte(pair.content), 0644) c.Assert(err, jc.ErrorIsNil) } var stor statetesting.MapStorage s.PatchValue(&newStateStorage, func(string, *mgo.Session) statestorage.Storage { return &stor }) _, cmd, err := s.initBootstrapCommand( c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--image-metadata", metadataDir, ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) // The contents of the directory should have been added to // environment storage. for _, pair := range expected { r, length, err := stor.Get(pair.path) c.Assert(err, jc.ErrorIsNil) data, err := ioutil.ReadAll(r) r.Close() c.Assert(err, jc.ErrorIsNil) c.Assert(length, gc.Equals, int64(len(pair.content))) c.Assert(data, gc.HasLen, int(length)) c.Assert(string(data), gc.Equals, pair.content) } }
func (s *BootstrapSuite) TestStructuredImageMetadataInvalidSeries(c *gc.C) { dir, _, _ := createImageMetadata(c) msg := "my test error" s.PatchValue(&seriesFromVersion, func(string) (string, error) { return "", errors.New(msg) }) _, cmd, err := s.initBootstrapCommand( c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId), "--image-metadata", dir, ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, gc.ErrorMatches, fmt.Sprintf(".*%v.*", msg)) }
func (s *BootstrapSuite) TestGUIArchiveSuccess(c *gc.C) { _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId)) c.Assert(err, jc.ErrorIsNil) var tw loggo.TestWriter err = loggo.RegisterWriter("bootstrap-test", &tw, loggo.DEBUG) c.Assert(err, jc.ErrorIsNil) defer loggo.RemoveWriter("bootstrap-test") err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) c.Assert(tw.Log(), jc.LogMatches, jc.SimpleMessages{{ loggo.DEBUG, `Juju GUI successfully set up`, }}) // Retrieve the state so that it is possible to access the GUI storage. st, err := state.Open(testing.ModelTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPassword, }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() // The GUI archive has been uploaded to the GUI storage. storage, err := st.GUIStorage() c.Assert(err, jc.ErrorIsNil) defer storage.Close() allMeta, err := storage.AllMetadata() c.Assert(err, jc.ErrorIsNil) c.Assert(allMeta, gc.HasLen, 1) c.Assert(allMeta[0].Version, gc.Equals, "2.0.42") // The current GUI version has been set. vers, err := st.GUIVersion() c.Assert(err, jc.ErrorIsNil) c.Assert(vers.String(), gc.Equals, "2.0.42") }
func (s *BootstrapSuite) TestStructuredImageMetadataStored(c *gc.C) { dir, m, _ := createImageMetadata(c) _, cmd, err := s.initBootstrapCommand( c, nil, "--model-config", s.b64yamlControllerModelConfig, "--hosted-model-config", s.b64yamlHostedModelConfig, "--instance-id", string(s.instanceId), "--image-metadata", dir, ) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) // This metadata should have also been written to state... // m.Version would be deduced from m.Series m.Version = "14.04" assertWrittenToState(c, m) }
func (s *BootstrapSuite) TestConfiguredMachineJobs(c *gc.C) { jobs := []multiwatcher.MachineJob{multiwatcher.JobManageEnviron} _, cmd, err := s.initBootstrapCommand(c, jobs, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId)) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) st, err := state.Open(testing.EnvironmentTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPasswordHash(), }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() m, err := st.Machine("0") c.Assert(err, jc.ErrorIsNil) c.Assert(m.Jobs(), gc.DeepEquals, []state.MachineJob{state.JobManageEnviron}) }