Beispiel #1
0
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)
	}
}
Beispiel #2
0
// 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()
}
Beispiel #3
0
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)
}
Beispiel #4
0
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")
}
Beispiel #5
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
}
Beispiel #6
0
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)
}
Beispiel #7
0
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)
}
Beispiel #8
0
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()
}
Beispiel #9
0
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)
}
Beispiel #10
0
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)
}
Beispiel #11
0
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)
}
Beispiel #12
0
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)
		}
	}
}
Beispiel #13
0
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: .*`,
	}})
}
Beispiel #14
0
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)
	}
}
Beispiel #15
0
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"`)
}
Beispiel #16
0
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)
}
Beispiel #17
0
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)
}
Beispiel #18
0
// 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
}
Beispiel #19
0
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)
	}
}
Beispiel #20
0
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)
	}
}
Beispiel #21
0
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")
}
Beispiel #22
0
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)
}
Beispiel #23
0
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
}
Beispiel #24
0
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)
}
Beispiel #25
0
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)
}
Beispiel #26
0
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)
	}
}
Beispiel #27
0
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))
}
Beispiel #28
0
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")
}
Beispiel #29
0
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)

}
Beispiel #30
0
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})
}