Пример #1
0
func (s *AllowedTargetVersionSuite) TestAllowedTargetVersionSuite(c *gc.C) {
	cases := []allowedTest{
		{current: "1.2.3", target: "1.3.3", allowed: true},
		{current: "1.2.3", target: "1.2.3", allowed: true},
		{current: "1.2.3", target: "2.2.3", allowed: true},
		{current: "1.2.3", target: "1.1.3", allowed: false},
		{current: "1.2.3", target: "1.2.2", allowed: true},
		{current: "1.2.3", target: "0.2.3", allowed: false},
	}
	for i, test := range cases {
		c.Logf("test case %d, %#v", i, test)
		current := version.MustParse(test.current)
		target := version.MustParse(test.target)
		c.Check(upgrader.AllowedTargetVersion(current, target), gc.Equals, test.allowed)
	}
}
Пример #2
0
func (st *State) checkCanUpgrade(currentVersion, newVersion string) error {
	matchCurrent := "^" + regexp.QuoteMeta(currentVersion) + "-"
	matchNew := "^" + regexp.QuoteMeta(newVersion) + "-"
	// Get all machines and units with a different or empty version.
	sel := bson.D{{"$or", []bson.D{
		{{"tools", bson.D{{"$exists", false}}}},
		{{"$and", []bson.D{
			{{"tools.version", bson.D{{"$not", bson.RegEx{matchCurrent, ""}}}}},
			{{"tools.version", bson.D{{"$not", bson.RegEx{matchNew, ""}}}}},
		}}},
	}}}
	var agentTags []string
	for _, collection := range []*mgo.Collection{st.machines, st.units} {
		var doc struct {
			Id string `bson:"_id"`
		}
		iter := collection.Find(sel).Select(bson.D{{"_id", 1}}).Iter()
		for iter.Next(&doc) {
			switch collection.Name {
			case "machines":
				agentTags = append(agentTags, names.MachineTag(doc.Id))
			case "units":
				agentTags = append(agentTags, names.UnitTag(doc.Id))
			}
		}
		if err := iter.Err(); err != nil {
			return err
		}
	}
	if len(agentTags) > 0 {
		return newVersionInconsistentError(version.MustParse(currentVersion), agentTags)
	}
	return nil
}
Пример #3
0
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})
}
Пример #4
0
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")
}
Пример #5
0
func (s *machineUpgraderSuite) TestWatchAPIVersion(c *gc.C) {
	w, err := s.st.WatchAPIVersion(s.rawMachine.Tag())
	c.Assert(err, gc.IsNil)
	defer statetesting.AssertStop(c, w)
	wc := statetesting.NewNotifyWatcherC(c, s.BackingState, w)
	// Initial event
	wc.AssertOneChange()
	vers := version.MustParse("10.20.34")
	err = statetesting.SetAgentVersion(s.BackingState, vers)
	c.Assert(err, gc.IsNil)
	// One change noticing the new version
	wc.AssertOneChange()
	// Setting the version to the same value doesn't trigger a change
	err = statetesting.SetAgentVersion(s.BackingState, vers)
	c.Assert(err, gc.IsNil)
	wc.AssertNoChange()
	vers = version.MustParse("10.20.35")
	err = statetesting.SetAgentVersion(s.BackingState, vers)
	c.Assert(err, gc.IsNil)
	wc.AssertOneChange()
	statetesting.AssertStop(c, w)
	wc.AssertClosed()
}
Пример #6
0
func (s *BootstrapSuite) TestAutoSyncLocalSource(c *gc.C) {
	sourceDir := createToolsSource(c, vAll)
	s.PatchValue(&version.Current.Number, version.MustParse("1.2.0"))
	env := resetJujuHome(c)

	// Bootstrap the environment with the valid source.
	// The bootstrapping has to show no error, because the tools
	// are automatically synchronized.
	_, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), "--metadata-source", sourceDir)
	c.Assert(err, gc.IsNil)

	// Now check the available tools which are the 1.2.0 envtools.
	checkTools(c, env, v120All)
}
Пример #7
0
func (s *BootstrapSuite) TestInvalidLocalSource(c *gc.C) {
	s.PatchValue(&version.Current.Number, version.MustParse("1.2.0"))
	env := resetJujuHome(c)

	// Bootstrap the environment with an invalid source.
	// The command returns with an error.
	_, err := coretesting.RunCommand(c, envcmd.Wrap(&BootstrapCommand{}), "--metadata-source", c.MkDir())
	c.Check(err, gc.ErrorMatches, "cannot upload bootstrap tools: Juju "+
		"cannot bootstrap because no tools are available for your "+
		"environment(.|\n)*")

	// Now check that there are no tools available.
	_, err = envtools.FindTools(
		env, version.Current.Major, version.Current.Minor, coretools.Filter{}, envtools.DoNotAllowRetry)
	c.Assert(err, gc.FitsTypeOf, errors.NotFoundf(""))
}
Пример #8
0
func opClientSetEnvironAgentVersion(c *gc.C, st *api.State, mst *state.State) (func(), error) {
	attrs, err := st.Client().EnvironmentGet()
	if err != nil {
		return func() {}, err
	}
	err = st.Client().SetEnvironAgentVersion(version.Current.Number)
	if err != nil {
		return func() {}, err
	}

	return func() {
		oldAgentVersion, found := attrs["agent-version"]
		if found {
			versionString := oldAgentVersion.(string)
			st.Client().SetEnvironAgentVersion(version.MustParse(versionString))
		}
	}, nil
}
Пример #9
0
func (s *BootstrapSuite) setupAutoUploadTest(c *gc.C, vers, series string) environs.Environ {
	s.PatchValue(&envtools.BundleTools, toolstesting.GetMockBundleTools(c))
	sourceDir := createToolsSource(c, vAll)
	s.PatchValue(&envtools.DefaultBaseURL, sourceDir)

	// Change the tools location to be the test location and also
	// the version and ensure their later restoring.
	// Set the current version to be something for which there are no tools
	// so we can test that an upload is forced.
	origVersion := version.Current
	version.Current.Number = version.MustParse(vers)
	version.Current.Series = series
	s.AddCleanup(func(*gc.C) { version.Current = origVersion })

	// Create home with dummy provider and remove all
	// of its envtools.
	return resetJujuHome(c)
}
Пример #10
0
func (*suite) TestNumberMarshalUnmarshal(c *gc.C) {
	for _, m := range marshallers {
		c.Logf("encoding %v", m.name)
		type doc struct {
			Version *version.Number
		}
		// Work around goyaml bug #1096149
		// SetYAML is not called for non-pointer fields.
		np := version.MustParse("1.2.3")
		v := doc{&np}
		data, err := m.marshal(&v)
		c.Assert(err, gc.IsNil)
		var nv doc
		err = m.unmarshal(data, &nv)
		c.Assert(err, gc.IsNil)
		c.Assert(nv, gc.DeepEquals, v)
	}
}
Пример #11
0
func (s *upgraderSuite) TestWatchAPIVersion(c *gc.C) {
	args := params.Entities{
		Entities: []params.Entity{{Tag: s.rawMachine.Tag()}},
	}
	results, err := s.upgrader.WatchAPIVersion(args)
	c.Assert(err, gc.IsNil)
	c.Check(results.Results, gc.HasLen, 1)
	c.Check(results.Results[0].NotifyWatcherId, gc.Not(gc.Equals), "")
	c.Check(results.Results[0].Error, gc.IsNil)
	resource := s.resources.Get(results.Results[0].NotifyWatcherId)
	c.Check(resource, gc.NotNil)

	w := resource.(state.NotifyWatcher)
	wc := statetesting.NewNotifyWatcherC(c, s.State, w)
	wc.AssertNoChange()

	err = statetesting.SetAgentVersion(s.State, version.MustParse("3.4.567.8"))
	c.Assert(err, gc.IsNil)
	wc.AssertOneChange()
	statetesting.AssertStop(c, w)
	wc.AssertClosed()
}
Пример #12
0
func (s *MachineSuite) TestMachineAgentUpgradeMongo(c *gc.C) {
	m, agentConfig, _ := s.primeAgent(c, version.Current, state.JobManageEnviron)
	agentConfig.SetUpgradedToVersion(version.MustParse("1.18.0"))
	err := agentConfig.Write()
	c.Assert(err, gc.IsNil)
	err = s.State.MongoSession().DB("admin").RemoveUser(m.Tag())
	c.Assert(err, gc.IsNil)

	s.agentSuite.PatchValue(&ensureMongoAdminUser, func(p mongo.EnsureAdminUserParams) (bool, error) {
		err := s.State.MongoSession().DB("admin").AddUser(p.User, p.Password, false)
		c.Assert(err, gc.IsNil)
		return true, nil
	})

	stateOpened := make(chan eitherState, 1)
	s.agentSuite.PatchValue(&reportOpenedState, func(st eitherState) {
		select {
		case stateOpened <- st:
		default:
		}
	})

	// Start the machine agent, and wait for state to be opened.
	a := s.newAgent(c, m)
	done := make(chan error)
	go func() { done <- a.Run(nil) }()
	defer a.Stop() // in case of failure
	select {
	case st := <-stateOpened:
		c.Assert(st, gc.NotNil)
	case <-time.After(coretesting.LongWait):
		c.Fatalf("state not opened")
	}
	s.waitStopped(c, state.JobManageEnviron, a, done)
	c.Assert(s.fakeEnsureMongo.ensureCount, gc.Equals, 1)
	c.Assert(s.fakeEnsureMongo.initiateCount, gc.Equals, 1)
}
Пример #13
0
	c.Logf("removing files: %v", names)
	for _, name := range names {
		err = stor.Remove(name)
		c.Check(err, gc.IsNil)
	}
	RemoveFakeToolsMetadata(c, stor)
}

// RemoveAllTools deletes all tools from the supplied environment.
func RemoveAllTools(c *gc.C, env environs.Environ) {
	c.Logf("clearing private storage")
	RemoveTools(c, env.Storage())
}

var (
	V100    = version.MustParse("1.0.0")
	V100p64 = version.MustParseBinary("1.0.0-precise-amd64")
	V100p32 = version.MustParseBinary("1.0.0-precise-i386")
	V100p   = []version.Binary{V100p64, V100p32}

	V100q64 = version.MustParseBinary("1.0.0-quantal-amd64")
	V100q32 = version.MustParseBinary("1.0.0-quantal-i386")
	V100q   = []version.Binary{V100q64, V100q32}
	V100all = append(V100p, V100q...)

	V1001    = version.MustParse("1.0.0.1")
	V1001p64 = version.MustParseBinary("1.0.0.1-precise-amd64")
	V100Xall = append(V100all, V1001p64)

	V110    = version.MustParse("1.1.0")
	V110p64 = version.MustParseBinary("1.1.0-precise-amd64")
Пример #14
0
func (formatter_1_18) unmarshal(data []byte) (*configInternal, error) {
	// NOTE: this needs to handle the absence of StatePort and get it from the
	// address
	var format format_1_18Serialization
	if err := goyaml.Unmarshal(data, &format); err != nil {
		return nil, err
	}
	if format.UpgradedToVersion == nil || *format.UpgradedToVersion == version.Zero {
		// Assume we upgrade from 1.16.
		upgradedToVersion := version.MustParse("1.16.0")
		format.UpgradedToVersion = &upgradedToVersion
	}
	config := &configInternal{
		tag:               format.Tag,
		dataDir:           format.DataDir,
		logDir:            format.LogDir,
		jobs:              format.Jobs,
		upgradedToVersion: *format.UpgradedToVersion,
		nonce:             format.Nonce,
		caCert:            format.CACert,
		oldPassword:       format.OldPassword,
		values:            format.Values,
	}
	if config.logDir == "" {
		config.logDir = DefaultLogDir
	}
	if config.dataDir == "" {
		config.dataDir = DefaultDataDir
	}
	if len(format.StateAddresses) > 0 {
		config.stateDetails = &connectionDetails{
			format.StateAddresses,
			format.StatePassword,
		}
	}
	if len(format.APIAddresses) > 0 {
		config.apiDetails = &connectionDetails{
			format.APIAddresses,
			format.APIPassword,
		}
	}
	if len(format.StateServerKey) != 0 {
		config.servingInfo = &params.StateServingInfo{
			Cert:           format.StateServerCert,
			PrivateKey:     format.StateServerKey,
			APIPort:        format.APIPort,
			StatePort:      format.StatePort,
			SharedSecret:   format.SharedSecret,
			SystemIdentity: format.SystemIdentity,
		}
		// There's a private key, then we need the state port,
		// which wasn't always in the  1.18 format. If it's not present
		// we can infer it from the ports in the state addresses.
		if config.servingInfo.StatePort == 0 {
			if len(format.StateAddresses) == 0 {
				return nil, fmt.Errorf("server key found but no state port")
			}

			_, portString, err := net.SplitHostPort(format.StateAddresses[0])
			if err != nil {
				return nil, err
			}
			statePort, err := strconv.Atoi(portString)
			if err != nil {
				return nil, err
			}
			config.servingInfo.StatePort = statePort
		}

	}
	return config, nil
}
Пример #15
0
func isPreHAVersion(v version.Number) bool {
	return v.Compare(version.MustParse("1.19.0")) < 0
}
Пример #16
0
func (test configTest) check(c *gc.C, home *testing.FakeHome) {
	cfg, err := config.New(test.useDefaults, test.attrs)
	if test.err != "" {
		c.Check(cfg, gc.IsNil)
		c.Assert(err, gc.ErrorMatches, test.err)
		return
	}
	c.Assert(err, gc.IsNil)

	typ, _ := test.attrs["type"].(string)
	// "null" has been deprecated in favour of "manual",
	// and is automatically switched.
	if typ == "null" {
		typ = "manual"
	}
	name, _ := test.attrs["name"].(string)
	c.Assert(cfg.Type(), gc.Equals, typ)
	c.Assert(cfg.Name(), gc.Equals, name)
	agentVersion, ok := cfg.AgentVersion()
	if s := test.attrs["agent-version"]; s != nil {
		c.Assert(ok, jc.IsTrue)
		c.Assert(agentVersion, gc.Equals, version.MustParse(s.(string)))
	} else {
		c.Assert(ok, jc.IsFalse)
		c.Assert(agentVersion, gc.Equals, version.Zero)
	}

	if statePort, ok := test.attrs["state-port"]; ok {
		c.Assert(cfg.StatePort(), gc.Equals, statePort)
	}
	if apiPort, ok := test.attrs["api-port"]; ok {
		c.Assert(cfg.APIPort(), gc.Equals, apiPort)
	}
	if syslogPort, ok := test.attrs["syslog-port"]; ok {
		c.Assert(cfg.SyslogPort(), gc.Equals, syslogPort)
	}

	dev, _ := test.attrs["development"].(bool)
	c.Assert(cfg.Development(), gc.Equals, dev)

	testmode, _ := test.attrs["test-mode"].(bool)
	c.Assert(cfg.TestMode(), gc.Equals, testmode)

	series, _ := test.attrs["default-series"].(string)
	if defaultSeries, ok := cfg.DefaultSeries(); ok {
		c.Assert(defaultSeries, gc.Equals, series)
	} else {
		c.Assert(series, gc.Equals, "")
		c.Assert(defaultSeries, gc.Equals, "")
	}

	if m, _ := test.attrs["firewall-mode"].(string); m != "" {
		c.Assert(cfg.FirewallMode(), gc.Equals, m)
	}
	if secret, _ := test.attrs["admin-secret"].(string); secret != "" {
		c.Assert(cfg.AdminSecret(), gc.Equals, secret)
	}

	if path, _ := test.attrs["authorized-keys-path"].(string); path != "" {
		c.Assert(cfg.AuthorizedKeys(), gc.Equals, home.FileContents(c, path))
		c.Assert(cfg.AllAttrs()["authorized-keys-path"], gc.IsNil)
	} else if keys, _ := test.attrs["authorized-keys"].(string); keys != "" {
		c.Assert(cfg.AuthorizedKeys(), gc.Equals, keys)
	} else {
		// Content of all the files that are read by default.
		c.Assert(cfg.AuthorizedKeys(), gc.Equals, "dsa\nrsa\nidentity\n")
	}

	cert, certPresent := cfg.CACert()
	if path, _ := test.attrs["ca-cert-path"].(string); path != "" {
		c.Assert(certPresent, jc.IsTrue)
		c.Assert(string(cert), gc.Equals, home.FileContents(c, path))
	} else if v, ok := test.attrs["ca-cert"].(string); v != "" {
		c.Assert(certPresent, jc.IsTrue)
		c.Assert(string(cert), gc.Equals, v)
	} else if ok {
		c.Check(cert, gc.HasLen, 0)
		c.Assert(certPresent, jc.IsFalse)
	} else if bool(test.useDefaults) && home.FileExists(".juju/my-name-cert.pem") {
		c.Assert(certPresent, jc.IsTrue)
		c.Assert(string(cert), gc.Equals, home.FileContents(c, "my-name-cert.pem"))
	} else {
		c.Check(cert, gc.HasLen, 0)
		c.Assert(certPresent, jc.IsFalse)
	}

	key, keyPresent := cfg.CAPrivateKey()
	if path, _ := test.attrs["ca-private-key-path"].(string); path != "" {
		c.Assert(keyPresent, jc.IsTrue)
		c.Assert(string(key), gc.Equals, home.FileContents(c, path))
	} else if v, ok := test.attrs["ca-private-key"].(string); v != "" {
		c.Assert(keyPresent, jc.IsTrue)
		c.Assert(string(key), gc.Equals, v)
	} else if ok {
		c.Check(key, gc.HasLen, 0)
		c.Assert(keyPresent, jc.IsFalse)
	} else if bool(test.useDefaults) && home.FileExists(".juju/my-name-private-key.pem") {
		c.Assert(keyPresent, jc.IsTrue)
		c.Assert(string(key), gc.Equals, home.FileContents(c, "my-name-private-key.pem"))
	} else {
		c.Check(key, gc.HasLen, 0)
		c.Assert(keyPresent, jc.IsFalse)
	}

	if v, ok := test.attrs["ssl-hostname-verification"]; ok {
		c.Assert(cfg.SSLHostnameVerification(), gc.Equals, v)
	}

	if v, ok := test.attrs["provisioner-safe-mode"]; ok {
		c.Assert(cfg.ProvisionerSafeMode(), gc.Equals, v)
	} else {
		c.Assert(cfg.ProvisionerSafeMode(), gc.Equals, false)
	}
	sshOpts := cfg.BootstrapSSHOpts()
	test.assertDuration(
		c,
		"bootstrap-timeout",
		sshOpts.Timeout,
		config.DefaultBootstrapSSHTimeout,
	)
	test.assertDuration(
		c,
		"bootstrap-retry-delay",
		sshOpts.RetryDelay,
		config.DefaultBootstrapSSHRetryDelay,
	)
	test.assertDuration(
		c,
		"bootstrap-addresses-delay",
		sshOpts.AddressesDelay,
		config.DefaultBootstrapSSHAddressesDelay,
	)

	if v, ok := test.attrs["image-stream"]; ok {
		c.Assert(cfg.ImageStream(), gc.Equals, v)
	} else {
		c.Assert(cfg.ImageStream(), gc.Equals, "released")
	}

	url, urlPresent := cfg.ImageMetadataURL()
	if v, _ := test.attrs["image-metadata-url"].(string); v != "" {
		c.Assert(url, gc.Equals, v)
		c.Assert(urlPresent, jc.IsTrue)
	} else {
		c.Assert(urlPresent, jc.IsFalse)
	}
	toolsURL, urlPresent := cfg.ToolsURL()
	oldToolsURL, oldURLPresent := cfg.AllAttrs()["tools-url"]
	oldToolsURLAttrValue, oldURLAttrPresent := test.attrs["tools-url"]
	expectedToolsURLValue := test.attrs["tools-metadata-url"]
	if expectedToolsURLValue == nil {
		expectedToolsURLValue = oldToolsURLAttrValue
	}
	if expectedToolsURLValue != nil && expectedToolsURLValue != "" {
		c.Assert(expectedToolsURLValue, gc.Equals, "tools-metadata-url-value")
		c.Assert(toolsURL, gc.Equals, expectedToolsURLValue)
		c.Assert(urlPresent, jc.IsTrue)
		c.Assert(oldToolsURL, gc.Equals, expectedToolsURLValue)
		c.Assert(oldURLPresent, jc.IsTrue)
	} else {
		c.Assert(urlPresent, jc.IsFalse)
		c.Assert(oldURLAttrPresent, jc.IsFalse)
		c.Assert(oldToolsURL, gc.Equals, "")
	}

	useLxcClone, useLxcClonePresent := cfg.LXCUseClone()
	oldUseClone, oldUseClonePresent := cfg.AllAttrs()["lxc-use-clone"]
	if v, ok := test.attrs["lxc-clone"]; ok {
		c.Assert(useLxcClone, gc.Equals, v)
		c.Assert(useLxcClonePresent, jc.IsTrue)
	} else {
		if oldUseClonePresent {
			c.Assert(useLxcClonePresent, jc.IsTrue)
			c.Assert(useLxcClone, gc.Equals, oldUseClone)
		} else {
			c.Assert(useLxcClonePresent, jc.IsFalse)
			c.Assert(useLxcClone, gc.Equals, false)
		}
	}
	useLxcCloneAufs, ok := cfg.LXCUseCloneAUFS()
	if v, ok := test.attrs["lxc-clone-aufs"]; ok {
		c.Assert(useLxcCloneAufs, gc.Equals, v)
	} else {
		c.Assert(useLxcCloneAufs, gc.Equals, false)
	}
}