예제 #1
0
// Validate makes sure that any labels specifed in Storage or Interfaces
// are unique, and that the required specifications are valid.
func (a *AllocateMachineArgs) Validate() error {
	storageLabels := set.NewStrings()
	for _, spec := range a.Storage {
		if err := spec.Validate(); err != nil {
			return errors.Annotate(err, "Storage")
		}
		if spec.Label != "" {
			if storageLabels.Contains(spec.Label) {
				return errors.NotValidf("reusing storage label %q", spec.Label)
			}
			storageLabels.Add(spec.Label)
		}
	}
	interfaceLabels := set.NewStrings()
	for _, spec := range a.Interfaces {
		if err := spec.Validate(); err != nil {
			return errors.Annotate(err, "Interfaces")
		}
		if interfaceLabels.Contains(spec.Label) {
			return errors.NotValidf("reusing interface label %q", spec.Label)
		}
		interfaceLabels.Add(spec.Label)
	}
	for _, v := range a.NotSpace {
		if v == "" {
			return errors.NotValidf("empty NotSpace constraint")
		}
	}
	return nil
}
예제 #2
0
func (s *filesSuite) checkSameStrings(c *gc.C, actual, expected []string) {
	sActual := set.NewStrings(actual...)
	sExpected := set.NewStrings(expected...)

	sActualOnly := sActual.Difference(sExpected)
	sExpectedOnly := sExpected.Difference(sActual)

	if !sActualOnly.IsEmpty() || !sExpectedOnly.IsEmpty() {
		c.Error("strings mismatch")
		onlyActual := sActualOnly.Values()
		onlyExpected := sExpectedOnly.Values()
		sort.Strings(onlyActual)
		sort.Strings(onlyExpected)

		if !sActualOnly.IsEmpty() {
			c.Log("...unexpected values:")
			for _, str := range onlyActual {
				c.Log(" " + str)
			}
		}
		if !sExpectedOnly.IsEmpty() {
			c.Log("...missing values:")
			for _, str := range onlyExpected {
				c.Log(" " + str)
			}
		}
	}
}
예제 #3
0
파일: deploy_test.go 프로젝트: bac/juju
func (s *DeployLocalSuite) assertMachines(c *gc.C, service *state.Application, expectCons constraints.Value, expectIds ...string) {
	units, err := service.AllUnits()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(units, gc.HasLen, len(expectIds))
	// first manually tell state to assign all the units
	for _, unit := range units {
		id := unit.Tag().Id()
		res, err := s.State.AssignStagedUnits([]string{id})
		c.Assert(err, jc.ErrorIsNil)
		c.Assert(res[0].Error, jc.ErrorIsNil)
		c.Assert(res[0].Unit, gc.Equals, id)
	}

	// refresh the list of units from state
	units, err = service.AllUnits()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(units, gc.HasLen, len(expectIds))
	unseenIds := set.NewStrings(expectIds...)
	for _, unit := range units {
		id, err := unit.AssignedMachineId()
		c.Assert(err, jc.ErrorIsNil)
		unseenIds.Remove(id)
		machine, err := s.State.Machine(id)
		c.Assert(err, jc.ErrorIsNil)
		cons, err := machine.Constraints()
		c.Assert(err, jc.ErrorIsNil)
		c.Assert(cons, gc.DeepEquals, expectCons)
	}
	c.Assert(unseenIds, gc.DeepEquals, set.NewStrings())
}
예제 #4
0
func (s *MigrationSuite) TestSSHHostKeyDocFields(c *gc.C) {
	ignored := set.NewStrings()
	migrated := set.NewStrings(
		"Keys",
	)
	s.AssertExportedFields(c, sshHostKeysDoc{}, migrated.Union(ignored))
}
예제 #5
0
func (s *MigrationSuite) TestBlockDeviceFields(c *gc.C) {
	ignored := set.NewStrings(
		"DocID",
		"ModelUUID",
		// We manage machine through containment.
		"Machine",
	)
	migrated := set.NewStrings(
		"BlockDevices",
	)
	s.AssertExportedFields(c, blockDevicesDoc{}, migrated.Union(ignored))
	// The meat is in the type stored in "BlockDevices".
	migrated = set.NewStrings(
		"DeviceName",
		"DeviceLinks",
		"Label",
		"UUID",
		"HardwareId",
		"BusAddress",
		"Size",
		"FilesystemType",
		"InUse",
		"MountPoint",
	)
	s.AssertExportedFields(c, BlockDeviceInfo{}, migrated)
}
예제 #6
0
파일: upgrade.go 프로젝트: zhouqt/juju
// AllProvisionedStateServersReady returns true if and only if all state servers
// that have been started by the provisioner have called EnsureUpgradeInfo with
// matching versions.
//
// When this returns true the master state state server can begin it's
// own upgrade.
func (info *UpgradeInfo) AllProvisionedStateServersReady() (bool, error) {
	// Get current state servers.
	stateServerInfo, err := info.st.StateServerInfo()
	if err != nil {
		return false, errors.Annotate(err, "cannot read state servers")
	}

	// Extract current and provisioned state servers.
	sel := bson.D{{
		"_id", bson.D{{"$in", stateServerInfo.MachineIds}},
	}}

	instanceData, closer := info.st.getCollection(instanceDataC)
	defer closer()
	iter := instanceData.Find(sel).Select(bson.D{{"_id", 1}}).Iter()

	var doc struct {
		Id string `bson:"_id"`
	}
	provisionedMachineIds := set.NewStrings()
	for iter.Next(&doc) {
		provisionedMachineIds.Add(doc.Id)
	}
	if err := iter.Close(); err != nil {
		return false, errors.Annotate(err, "cannot read provisioned machines")
	}
	// Find provisioned state machines that haven't indicated
	// themselves as ready for upgrade.
	missingMachineIds := provisionedMachineIds.Difference(
		set.NewStrings(info.doc.StateServersReady...),
	)
	return missingMachineIds.IsEmpty(), nil
}
예제 #7
0
func (s *facadeVersionSuite) TestFacadeVersionsMatchServerVersions(c *gc.C) {
	// The client side code doesn't want to directly import the server side
	// code just to list out what versions are available. However, we do
	// want to make sure that the two sides are kept in sync.
	clientFacadeNames := set.NewStrings()
	for name, version := range *api.FacadeVersions {
		clientFacadeNames.Add(name)
		// All versions should now be non-zero.
		c.Check(version, jc.GreaterThan, 0)
	}
	// Register the components.
	all.RegisterForServer()
	allServerFacades := common.Facades.List()
	serverFacadeNames := set.NewStrings()
	serverFacadeBestVersions := make(map[string]int, len(allServerFacades))
	for _, facade := range allServerFacades {
		serverFacadeNames.Add(facade.Name)
		serverFacadeBestVersions[facade.Name] = facade.Versions[len(facade.Versions)-1]
	}
	// First check that both sides know about all the same versions
	c.Check(serverFacadeNames.Difference(clientFacadeNames).SortedValues(), gc.HasLen, 0)
	c.Check(clientFacadeNames.Difference(serverFacadeNames).SortedValues(), gc.HasLen, 0)
	// Next check that the best versions match
	c.Check(*api.FacadeVersions, jc.DeepEquals, serverFacadeBestVersions)
}
예제 #8
0
파일: main_test.go 프로젝트: kat-co/juju
func (s *MainSuite) TestHelpCommands(c *gc.C) {
	// Check that we have correctly registered all the commands
	// by checking the help output.
	// First check default commands, and then check commands that are
	// activated by feature flags.

	// remove features behind dev_flag for the first test
	// since they are not enabled.
	cmdSet := set.NewStrings(commandNames...)

	// 1. Default Commands. Disable all features.
	setFeatureFlags("")
	// Use sorted values here so we can better see what is wrong.
	registered := getHelpCommandNames(c)
	unknown := registered.Difference(cmdSet)
	c.Assert(unknown, jc.DeepEquals, set.NewStrings())
	missing := cmdSet.Difference(registered)
	c.Assert(missing, jc.DeepEquals, set.NewStrings())

	// 2. Enable development features, and test again.
	cmdSet = cmdSet.Union(commandNamesBehindFlags)
	setFeatureFlags(strings.Join(devFeatures, ","))
	registered = getHelpCommandNames(c)
	unknown = registered.Difference(cmdSet)
	c.Assert(unknown, jc.DeepEquals, set.NewStrings())
	missing = cmdSet.Difference(registered)
	c.Assert(missing, jc.DeepEquals, set.NewStrings())
}
예제 #9
0
func (s *networkerSuite) TestPrimaryOrLoopbackInterfacesAreSkipped(c *gc.C) {
	// Reset what's considered up, so we can test eth0 and lo are not
	// touched.
	s.upInterfaces = set.NewStrings()
	s.interfacesWithAddress = set.NewStrings()

	nw, _ := s.newCustomNetworker(c, s.apiFacade, s.stateMachine.Id(), true, false)
	defer worker.Stop(nw)

	timeout := time.After(coretesting.LongWait)
	for {
		select {
		case <-s.lastCommands:
			if !s.vlanModuleLoaded {
				// VLAN module loading commands is one of the first things
				// the worker does, so if hasn't happened, we wait a bit more.
				continue
			}
			c.Assert(s.upInterfaces.Contains("lo"), jc.IsFalse)
			c.Assert(s.upInterfaces.Contains("eth0"), jc.IsFalse)
			if s.upInterfaces.Contains("eth1") {
				// If we run ifup eth1, we successfully skipped lo and
				// eth0.
				s.assertHaveConfig(c, nw, "", "eth0", "eth1", "eth1.42", "eth0.69")
				return
			}
		case <-timeout:
			c.Fatalf("commands expected but not executed")
		}
	}
}
예제 #10
0
파일: worker_test.go 프로젝트: OSBI/juju
func (s *workerSuite) TestConvertSpaceName(c *gc.C) {
	empty := set.Strings{}
	nameTests := []struct {
		name     string
		existing set.Strings
		expected string
	}{
		{"foo", empty, "foo"},
		{"foo1", empty, "foo1"},
		{"Foo Thing", empty, "foo-thing"},
		{"foo^9*//++!!!!", empty, "foo9"},
		{"--Foo", empty, "foo"},
		{"---^^&*()!", empty, "empty"},
		{" ", empty, "empty"},
		{"", empty, "empty"},
		{"foo\u2318", empty, "foo"},
		{"foo--", empty, "foo"},
		{"-foo--foo----bar-", empty, "foo-foo-bar"},
		{"foo-", set.NewStrings("foo", "bar", "baz"), "foo-2"},
		{"foo", set.NewStrings("foo", "foo-2"), "foo-3"},
		{"---", set.NewStrings("empty"), "empty-2"},
	}
	for _, test := range nameTests {
		result := discoverspaces.ConvertSpaceName(test.name, test.existing)
		c.Check(result, gc.Equals, test.expected)
	}
}
예제 #11
0
func (s *MigrationSuite) TestUnitDocFields(c *gc.C) {
	ignored := set.NewStrings(
		"ModelUUID",
		"DocID",
		"Life",
		// Application is implicit in the migration structure through containment.
		"Application",
		// Resolved is not migrated as we check that all is good before we start.
		"Resolved",
		// Series and CharmURL also come from the service.
		"Series",
		"CharmURL",
		"TxnRevno",
	)
	migrated := set.NewStrings(
		"Name",
		"Principal",
		"Subordinates",
		"StorageAttachmentCount",
		"MachineId",
		"Tools",
		"PasswordHash",
	)
	s.AssertExportedFields(c, unitDoc{}, migrated.Union(ignored))
}
예제 #12
0
파일: internal_test.go 프로젝트: bac/juju
func (s *cloudImageMetadataSuite) TestCloudImageMetadataDocFields(c *gc.C) {
	ignored := set.NewStrings("Id")
	migrated := set.NewStrings(
		"Stream",
		"Region",
		"Version",
		"Series",
		"Arch",
		"VirtType",
		"RootStorageType",
		"RootStorageSize",
		"Source",
		"Priority",
		"ImageId",
		"DateCreated",
	)
	fields := migrated.Union(ignored)
	expected := testing.GetExportedFields(imagesMetadataDoc{})
	unknown := expected.Difference(fields)
	removed := fields.Difference(expected)
	// If this test fails, it means that extra fields have been added to the
	// doc without thinking about the migration implications.
	c.Check(unknown, gc.HasLen, 0)
	c.Assert(removed, gc.HasLen, 0)
}
예제 #13
0
파일: config_test.go 프로젝트: exekias/juju
func (s *configFunctionalSuite) SetUpTest(c *gc.C) {
	s.configBaseSuite.SetUpTest(c)

	s.client = newLocalClient(c)

	origConfigDir := lxd.ConfigDir
	s.AddCleanup(func(c *gc.C) {
		lxd.ConfigDir = origConfigDir
	})

	if s.client != nil {
		origCerts, err := s.client.ListCerts()
		c.Assert(err, jc.ErrorIsNil)
		s.AddCleanup(func(c *gc.C) {
			certs, err := s.client.ListCerts()
			c.Assert(err, jc.ErrorIsNil)

			orig := set.NewStrings(origCerts...)
			added := set.NewStrings(certs...).Difference(orig)
			for _, fingerprint := range added.Values() {
				err := s.client.RemoveCertByFingerprint(fingerprint)
				if err != nil {
					c.Logf("could not remove cert %q: %v", fingerprint, err)
				}
			}
		})
	}
}
예제 #14
0
파일: manifolds_test.go 프로젝트: bac/juju
func (s *ManifoldsSuite) TestFlagDependencies(c *gc.C) {
	exclusions := set.NewStrings(
		"agent",
		"api-caller",
		"api-config-watcher",
		"clock",
		"spaces-imported-gate",
		"is-responsible-flag",
		"not-alive-flag",
		"not-dead-flag",
	)
	manifolds := model.Manifolds(model.ManifoldsConfig{
		Agent: &mockAgent{},
	})
	for name, manifold := range manifolds {
		c.Logf("checking %s", name)
		if exclusions.Contains(name) {
			continue
		}
		inputs := set.NewStrings(manifold.Inputs...)
		if !inputs.Contains("is-responsible-flag") {
			c.Check(inputs.Contains("migration-fortress"), jc.IsTrue)
			c.Check(inputs.Contains("migration-inactive-flag"), jc.IsTrue)
		}
	}
}
예제 #15
0
func (s *MigrationSuite) TestRelationDocFields(c *gc.C) {
	fields := set.NewStrings(
		// DocID itself isn't migrated
		"DocID",
		// ModelUUID shouldn't be exported, and is inherited
		// from the model definition.
		"ModelUUID",
		"Key",
		"Id",
		"Endpoints",
		// Life isn't exported, only alive.
		"Life",
		// UnitCount isn't explicitly exported, but defined by the stored
		// unit settings data for the relation endpoint.
		"UnitCount",
	)
	s.AssertExportedFields(c, relationDoc{}, fields)
	// We also need to check the Endpoint and nested charm.Relation field.
	endpointFields := set.NewStrings("ServiceName", "Relation")
	s.AssertExportedFields(c, Endpoint{}, endpointFields)
	charmRelationFields := set.NewStrings(
		"Name",
		"Role",
		"Interface",
		"Optional",
		"Limit",
		"Scope",
	)
	s.AssertExportedFields(c, charm.Relation{}, charmRelationFields)
}
예제 #16
0
파일: main_test.go 프로젝트: imoapps/juju
func (s *MainSuite) TestHelpCommands(c *gc.C) {
	defer osenv.SetJujuHome(osenv.SetJujuHome(c.MkDir()))

	// Check that we have correctly registered all the commands
	// by checking the help output.
	// First check default commands, and then check commands that are
	// activated by feature flags.

	// Here we can add feature flags for any commands we want to hide by default.
	devFeatures := []string{}

	// remove features behind dev_flag for the first test
	// since they are not enabled.
	cmdSet := set.NewStrings(commandNames...)
	for _, feature := range devFeatures {
		cmdSet.Remove(feature)
	}

	// 1. Default Commands. Disable all features.
	setFeatureFlags("")
	// Use sorted values here so we can better see what is wrong.
	registered := getHelpCommandNames(c)
	unknown := registered.Difference(cmdSet)
	c.Assert(unknown, jc.DeepEquals, set.NewStrings())
	missing := cmdSet.Difference(registered)
	c.Assert(missing, jc.DeepEquals, set.NewStrings())

	// 2. Enable development features, and test again.
	setFeatureFlags(strings.Join(devFeatures, ","))
	registered = getHelpCommandNames(c)
	unknown = registered.Difference(cmdSet)
	c.Assert(unknown, jc.DeepEquals, set.NewStrings())
	missing = cmdSet.Difference(registered)
	c.Assert(missing, jc.DeepEquals, set.NewStrings())
}
예제 #17
0
func (s *MigrationSuite) TestUnitDocFields(c *gc.C) {
	fields := set.NewStrings(
		// DocID itself isn't migrated
		"DocID",
		"Name",
		// ModelUUID shouldn't be exported, and is inherited
		// from the model definition.
		"ModelUUID",
		// Service is implicit in the migration structure through containment.
		"Service",
		// Series, CharmURL, and Channel also come from the service.
		"Series",
		"CharmURL",
		"Principal",
		"Subordinates",
		"MachineId",
		// Resolved is not migrated as we check that all is good before we start.
		"Resolved",
		"Tools",
		// Life isn't migrated as we only migrate live things.
		"Life",
		// TxnRevno isn't migrated.
		"TxnRevno",
		"PasswordHash",
		// Obsolete and not migrated.
		"Ports",
		"PublicAddress",
		"PrivateAddress",
	)
	todo := set.NewStrings(
		"StorageAttachmentCount",
	)

	s.AssertExportedFields(c, unitDoc{}, fields.Union(todo))
}
예제 #18
0
func (s *MigrationSuite) TestServiceDocFields(c *gc.C) {
	ignored := set.NewStrings(
		// DocID is the env + name
		"DocID",
		// ModelUUID shouldn't be exported, and is inherited
		// from the model definition.
		"ModelUUID",
		// Always alive, not explicitly exported.
		"Life",
		// OwnerTag is deprecated and should be deleted.
		"OwnerTag",
		// TxnRevno is mgo internals and should not be migrated.
		"TxnRevno",
		// UnitCount is handled by the number of units for the exported service.
		"UnitCount",
		// RelationCount is handled by the number of times the service name
		// appears in relation endpoints.
		"RelationCount",
	)
	migrated := set.NewStrings(
		"Name",
		"Series",
		"Subordinate",
		"CharmURL",
		"Channel",
		"CharmModifiedVersion",
		"ForceCharm",
		"Exposed",
		"MinUnits",
		"MetricCredentials",
	)
	s.AssertExportedFields(c, serviceDoc{}, migrated.Union(ignored))
}
예제 #19
0
파일: converter.go 프로젝트: rogpeppe/juju
// gitManifest returns every file path in the supplied directory, *except* for:
//    * paths below .git, because we don't need to track every file: we just
//      want them all gone
//    * charmURLPath, because we don't ever want to remove that: that's how
//      the manifestDeployer keeps track of what version it's upgrading from.
// All paths are slash-separated, to match the bundle manifest format.
func gitManifest(linkPath string) (set.Strings, error) {
	dirPath, err := os.Readlink(linkPath)
	if err != nil {
		return set.NewStrings(), err
	}
	manifest := set.NewStrings()
	err = filepath.Walk(dirPath, func(path string, fileInfo os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		relPath, err := filepath.Rel(dirPath, path)
		if err != nil {
			return err
		}
		switch relPath {
		case ".", charmURLPath:
			return nil
		case ".git":
			err = filepath.SkipDir
		}
		manifest.Add(filepath.ToSlash(relPath))
		return err
	})
	if err != nil {
		return set.NewStrings(), err
	}
	return manifest, nil
}
예제 #20
0
// Validate implements Model.
func (m *model) Validate() error {
	// A model needs an owner.
	if m.Owner_ == "" {
		return errors.NotValidf("missing model owner")
	}

	unitsWithOpenPorts := set.NewStrings()
	for _, machine := range m.Machines_.Machines_ {
		if err := machine.Validate(); err != nil {
			return errors.Trace(err)
		}
		for _, np := range machine.NetworkPorts() {
			for _, pr := range np.OpenPorts() {
				unitsWithOpenPorts.Add(pr.UnitName())
			}
		}
	}
	allUnits := set.NewStrings()
	for _, service := range m.Services_.Services_ {
		if err := service.Validate(); err != nil {
			return errors.Trace(err)
		}
		allUnits = allUnits.Union(service.unitNames())
	}
	// Make sure that all the unit names specified in machine opened ports
	// exist as units of services.
	unknownUnitsWithPorts := unitsWithOpenPorts.Difference(allUnits)
	if len(unknownUnitsWithPorts) > 0 {
		return errors.Errorf("unknown unit names in open ports: %s", unknownUnitsWithPorts.SortedValues())
	}

	return m.validateRelations()
}
예제 #21
0
파일: validation.go 프로젝트: jiasir/juju
// RegisterConflicts is defined on Validator.
func (v *validator) RegisterConflicts(reds, blues []string) {
	for _, red := range reds {
		v.conflicts[red] = set.NewStrings(blues...)
	}
	for _, blue := range blues {
		v.conflicts[blue] = set.NewStrings(reds...)
	}
}
예제 #22
0
파일: machineremovals.go 프로젝트: bac/juju
func collectMissingMachineIds(expectedIds []string, machines []*Machine) []string {
	expectedSet := set.NewStrings(expectedIds...)
	actualSet := set.NewStrings()
	for _, machine := range machines {
		actualSet.Add(machine.Id())
	}
	return expectedSet.Difference(actualSet).SortedValues()
}
예제 #23
0
func (stringSetSuite) TestIntersection(c *gc.C) {
	s1 := set.NewStrings("foo", "bar")
	s2 := set.NewStrings("foo", "baz", "bang")
	int1 := s1.Intersection(s2)
	int2 := s2.Intersection(s1)

	AssertValues(c, int1, "foo")
	AssertValues(c, int2, "foo")
}
예제 #24
0
// AllProvisionedControllersReady returns true if and only if all controllers
// that have been started by the provisioner have called EnsureUpgradeInfo with
// matching versions.
//
// When this returns true the master state controller can begin it's
// own upgrade.
func (info *UpgradeInfo) AllProvisionedControllersReady() (bool, error) {
	provisioned, err := info.getProvisionedControllers()
	if err != nil {
		return false, errors.Trace(err)
	}
	ready := set.NewStrings(info.doc.ControllersReady...)
	missing := set.NewStrings(provisioned...).Difference(ready)
	return missing.IsEmpty(), nil
}
예제 #25
0
func (stringSetSuite) TestUnion(c *gc.C) {
	s1 := set.NewStrings("foo", "bar")
	s2 := set.NewStrings("foo", "baz", "bang")
	union1 := s1.Union(s2)
	union2 := s2.Union(s1)

	AssertValues(c, union1, "foo", "bar", "baz", "bang")
	AssertValues(c, union2, "foo", "bar", "baz", "bang")
}
예제 #26
0
func (stringSetSuite) TestSize(c *gc.C) {
	// Empty sets are empty.
	s := set.NewStrings()
	c.Assert(s.Size(), gc.Equals, 0)

	// Size returns number of unique values.
	s = set.NewStrings("foo", "foo", "bar")
	c.Assert(s.Size(), gc.Equals, 2)
}
예제 #27
0
func (stringSetSuite) TestDifference(c *gc.C) {
	s1 := set.NewStrings("foo", "bar")
	s2 := set.NewStrings("foo", "baz", "bang")
	diff1 := s1.Difference(s2)
	diff2 := s2.Difference(s1)

	AssertValues(c, diff1, "bar")
	AssertValues(c, diff2, "baz", "bang")
}
예제 #28
0
파일: model.go 프로젝트: bac/juju
func (m *model) validateStorage(allMachineIDs, allApplications, allUnits set.Strings) error {
	appsAndUnits := allApplications.Union(allUnits)
	allStorage := set.NewStrings()
	for i, storage := range m.Storages_.Storages_ {
		if err := storage.Validate(); err != nil {
			return errors.Annotatef(err, "storage[%d]", i)
		}
		allStorage.Add(storage.Tag().Id())
		owner, err := storage.Owner()
		if err != nil {
			return errors.Wrap(err, errors.NotValidf("storage[%d] owner (%s)", i, owner))
		}
		ownerID := owner.Id()
		if !appsAndUnits.Contains(ownerID) {
			return errors.NotValidf("storage[%d] owner (%s)", i, ownerID)
		}
		for _, unit := range storage.Attachments() {
			if !allUnits.Contains(unit.Id()) {
				return errors.NotValidf("storage[%d] attachment referencing unknown unit %q", i, unit)
			}
		}
	}
	allVolumes := set.NewStrings()
	for i, volume := range m.Volumes_.Volumes_ {
		if err := volume.Validate(); err != nil {
			return errors.Annotatef(err, "volume[%d]", i)
		}
		allVolumes.Add(volume.Tag().Id())
		if storeID := volume.Storage().Id(); storeID != "" && !allStorage.Contains(storeID) {
			return errors.NotValidf("volume[%d] referencing unknown storage %q", i, storeID)
		}
		for j, attachment := range volume.Attachments() {
			if machineID := attachment.Machine().Id(); !allMachineIDs.Contains(machineID) {
				return errors.NotValidf("volume[%d].attachment[%d] referencing unknown machine %q", i, j, machineID)
			}
		}
	}
	for i, filesystem := range m.Filesystems_.Filesystems_ {
		if err := filesystem.Validate(); err != nil {
			return errors.Annotatef(err, "filesystem[%d]", i)
		}
		if storeID := filesystem.Storage().Id(); storeID != "" && !allStorage.Contains(storeID) {
			return errors.NotValidf("filesystem[%d] referencing unknown storage %q", i, storeID)
		}
		if volID := filesystem.Volume().Id(); volID != "" && !allVolumes.Contains(volID) {
			return errors.NotValidf("filesystem[%d] referencing unknown volume %q", i, volID)
		}
		for j, attachment := range filesystem.Attachments() {
			if machineID := attachment.Machine().Id(); !allMachineIDs.Contains(machineID) {
				return errors.NotValidf("filesystem[%d].attachment[%d] referencing unknown machine %q", i, j, machineID)
			}
		}
	}

	return nil
}
예제 #29
0
func (s *MigrationSuite) TestStorageConstraintsDocFields(c *gc.C) {
	ignored := set.NewStrings(
		"ModelUUID",
		"DocID",
	)
	migrated := set.NewStrings(
		"Constraints",
	)
	s.AssertExportedFields(c, storageConstraintsDoc{}, migrated.Union(ignored))
}
예제 #30
0
파일: model.go 프로젝트: bac/juju
// Validate implements Model.
func (m *model) Validate() error {
	// A model needs an owner.
	if m.Owner_ == "" {
		return errors.NotValidf("missing model owner")
	}
	allMachines := set.NewStrings()
	unitsWithOpenPorts := set.NewStrings()
	for _, machine := range m.Machines_.Machines_ {
		if err := m.validateMachine(machine, allMachines, unitsWithOpenPorts); err != nil {
			return errors.Trace(err)
		}
	}
	allApplications := set.NewStrings()
	allUnits := set.NewStrings()
	for _, application := range m.Applications_.Applications_ {
		if err := application.Validate(); err != nil {
			return errors.Trace(err)
		}
		allApplications.Add(application.Name())
		allUnits = allUnits.Union(application.unitNames())
	}
	// Make sure that all the unit names specified in machine opened ports
	// exist as units of applications.
	unknownUnitsWithPorts := unitsWithOpenPorts.Difference(allUnits)
	if len(unknownUnitsWithPorts) > 0 {
		return errors.Errorf("unknown unit names in open ports: %s", unknownUnitsWithPorts.SortedValues())
	}

	err := m.validateRelations()
	if err != nil {
		return errors.Trace(err)
	}

	err = m.validateSubnets()
	if err != nil {
		return errors.Trace(err)
	}

	err = m.validateLinkLayerDevices()
	if err != nil {
		return errors.Trace(err)
	}
	err = m.validateAddresses()
	if err != nil {
		return errors.Trace(err)
	}

	err = m.validateStorage(allMachines, allApplications, allUnits)
	if err != nil {
		return errors.Trace(err)
	}

	return nil
}