func (stringSetSuite) TestUninitialized(c *gc.C) { var uninitialized set.Strings c.Assert(uninitialized.Size(), gc.Equals, 0) c.Assert(uninitialized.IsEmpty(), gc.Equals, true) // You can get values and sorted values from an unitialized set. AssertValues(c, uninitialized) // All contains checks are false c.Assert(uninitialized.Contains("foo"), gc.Equals, false) // Remove works on an uninitialized Strings uninitialized.Remove("foo") var other set.Strings // Union returns a new set that is empty but initialized. c.Assert(uninitialized.Union(other), gc.DeepEquals, set.NewStrings()) c.Assert(uninitialized.Intersection(other), gc.DeepEquals, set.NewStrings()) c.Assert(uninitialized.Difference(other), gc.DeepEquals, set.NewStrings()) other = set.NewStrings("foo", "bar") c.Assert(uninitialized.Union(other), gc.DeepEquals, other) c.Assert(uninitialized.Intersection(other), gc.DeepEquals, set.NewStrings()) c.Assert(uninitialized.Difference(other), gc.DeepEquals, set.NewStrings()) c.Assert(other.Union(uninitialized), gc.DeepEquals, other) c.Assert(other.Intersection(uninitialized), gc.DeepEquals, set.NewStrings()) c.Assert(other.Difference(uninitialized), gc.DeepEquals, other) // Once something is added, the set becomes initialized. uninitialized.Add("foo") AssertValues(c, uninitialized, "foo") }
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) } } }
// fetchMachines returns a map from top level machine id to machines, where machines[0] is the host // machine and machines[1..n] are any containers (including nested ones). // // If machineIds is non-nil, only machines whose IDs are in the set are returned. func fetchMachines(st stateInterface, machineIds set.Strings) (map[string][]*state.Machine, error) { v := make(map[string][]*state.Machine) machines, err := st.AllMachines() if err != nil { return nil, err } // AllMachines gives us machines sorted by id. for _, m := range machines { if machineIds != nil && !machineIds.Contains(m.Id()) { continue } parentId, ok := m.ParentId() if !ok { // Only top level host machines go directly into the machine map. v[m.Id()] = []*state.Machine{m} } else { topParentId := state.TopParentId(m.Id()) machines, ok := v[topParentId] if !ok { panic(fmt.Errorf("unexpected machine id %q", parentId)) } machines = append(machines, m) v[topParentId] = machines } } return v, nil }
func (s *ModelConfigSourceSuite) assertModelConfigValues(c *gc.C, modelCfg *config.Config, modelAttributes, controllerAttributes set.Strings) { expectedValues := make(config.ConfigValues) defaultAttributes := set.NewStrings() for defaultAttr := range config.ConfigDefaults() { defaultAttributes.Add(defaultAttr) } for attr, val := range modelCfg.AllAttrs() { source := "model" if defaultAttributes.Contains(attr) { source = "default" } if modelAttributes.Contains(attr) { source = "model" } if controllerAttributes.Contains(attr) { source = "controller" } expectedValues[attr] = config.ConfigValue{ Value: val, Source: source, } } sources, err := s.State.ModelConfigValues() c.Assert(err, jc.ErrorIsNil) c.Assert(sources, jc.DeepEquals, expectedValues) }
// ConvertSpaceName returns a string derived from name that does not // already exist in existing. It does not modify existing. func ConvertSpaceName(name string, existing set.Strings) string { // First lower case and replace spaces with dashes. name = strings.Replace(name, " ", "-", -1) name = strings.ToLower(name) // Replace any character that isn't in the set "-", "a-z", "0-9". name = network.SpaceInvalidChars.ReplaceAllString(name, "") // Get rid of any dashes at the start as that isn't valid. name = dashPrefix.ReplaceAllString(name, "") // And any at the end. name = dashSuffix.ReplaceAllString(name, "") // Repleace multiple dashes with a single dash. name = multipleDashes.ReplaceAllString(name, "-") // Special case of when the space name was only dashes or invalid // characters! if name == "" { name = "empty" } // If this name is in use add a numerical suffix. if existing.Contains(name) { counter := 2 for existing.Contains(name + fmt.Sprintf("-%d", counter)) { counter += 1 } name = name + fmt.Sprintf("-%d", counter) } return name }
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) } }
// findAvailableTools returns a list of available tools, // including tools that may be locally built and then // uploaded. Tools that need to be built will have an // empty URL. func findAvailableTools(env environs.Environ, arch *string, upload bool) (coretools.List, error) { if upload { // We're forcing an upload: ensure we can do so. if err := validateUploadAllowed(env, arch); err != nil { return nil, err } return locallyBuildableTools(), nil } // We're not forcing an upload, so look for tools // in the environment's simplestreams search paths // for existing tools. var vers *version.Number if agentVersion, ok := env.Config().AgentVersion(); ok { vers = &agentVersion } dev := version.Current.IsDev() || env.Config().Development() logger.Debugf("looking for bootstrap tools: version=%v", vers) toolsList, findToolsErr := findBootstrapTools(env, vers, arch, dev) if findToolsErr != nil && !errors.IsNotFound(findToolsErr) { return nil, findToolsErr } if !dev || vers != nil { // We are not running a development build, or agent-version // was specified; the only tools available are the ones we've // just found. return toolsList, findToolsErr } // The tools located may not include the ones that the // provider requires. We are running a development build, // so augment the list of tools with those that we can build // locally. // Collate the set of arch+series that are externally available // so we can see if we need to build any locally. If we need // to, only then do we validate that we can upload (which // involves a potentially expensive SupportedArchitectures call). var archSeries set.Strings for _, tools := range toolsList { archSeries.Add(tools.Version.Arch + tools.Version.Series) } var localToolsList coretools.List for _, tools := range locallyBuildableTools() { if !archSeries.Contains(tools.Version.Arch + tools.Version.Series) { localToolsList = append(localToolsList, tools) } } if len(localToolsList) == 0 || validateUploadAllowed(env, arch) != nil { return toolsList, findToolsErr } return append(toolsList, localToolsList...), nil }
func (m *Machine) prepareOneSetDevicesAddresses(args *LinkLayerDeviceAddress, allProviderIDs set.Strings) (_ *ipAddressDoc, err error) { defer errors.DeferredAnnotatef(&err, "invalid address %q", args.CIDRAddress) if err := m.validateSetDevicesAddressesArgs(args); err != nil { return nil, errors.Trace(err) } if allProviderIDs.Contains(string(args.ProviderID)) { return nil, NewProviderIDNotUniqueError(args.ProviderID) } return m.newIPAddressDocFromArgs(args) }
func (m *Machine) prepareOneSetLinkLayerDeviceArgs(args *LinkLayerDeviceArgs, pendingNames set.Strings) (_ *linkLayerDeviceDoc, err error) { defer errors.DeferredAnnotatef(&err, "invalid device %q", args.Name) if err := m.validateSetLinkLayerDeviceArgs(args); err != nil { return nil, errors.Trace(err) } if pendingNames.Contains(args.Name) { return nil, errors.NewNotValid(nil, "Name specified more than once") } return m.newLinkLayerDeviceDocFromArgs(args), nil }
func mergedAddresses(machineAddresses, providerAddresses []address) []network.Address { merged := make([]network.Address, len(providerAddresses), len(providerAddresses)+len(machineAddresses)) var providerValues set.Strings for i, address := range providerAddresses { providerValues.Add(address.Value) merged[i] = address.InstanceAddress() } for _, address := range machineAddresses { if !providerValues.Contains(address.Value) { merged = append(merged, address.InstanceAddress()) } } return merged }
// AssertAllSpacesResult makes it easier to verify AllSpaces results. func (s *SubnetsSuite) AssertAllSpacesResult(c *gc.C, got params.SpaceResults, expected []common.BackingSpace) { seen := set.Strings{} results := []params.SpaceResult{} for _, space := range expected { if seen.Contains(space.Name()) { continue } seen.Add(space.Name()) result := params.SpaceResult{} result.Tag = names.NewSpaceTag(space.Name()).String() results = append(results, result) } c.Assert(got, jc.DeepEquals, params.SpaceResults{Results: results}) }
// merge cleans up the pending changes to account for actionId's being // removed before this watcher consumes them, and to account for the slight // potential overlap between the inital actionIds pending before the watcher // starts, and actionId's the watcher detects func (w *actionWatcher) merge(changes, initial set.Strings, updates map[interface{}]bool) error { for id, exists := range updates { switch id := id.(type) { case string: if exists { if !initial.Contains(id) { changes.Add(id) } } else { changes.Remove(id) } default: return errors.Errorf("id is not of type string, got %T", id) } } return nil }
// upgradeCertificateDNSNames ensure that the controller certificate // recorded in the agent config and also mongo server.pem contains the // DNSNames entries required by Juju. func upgradeCertificateDNSNames(config agent.ConfigSetter) error { si, ok := config.StateServingInfo() if !ok || si.CAPrivateKey == "" { // No certificate information exists yet, nothing to do. return nil } // Validate the current certificate and private key pair, and then // extract the current DNS names from the certificate. If the // certificate validation fails, or it does not contain the DNS // names we require, we will generate a new one. var dnsNames set.Strings serverCert, _, err := cert.ParseCertAndKey(si.Cert, si.PrivateKey) if err != nil { // The certificate is invalid, so create a new one. logger.Infof("parsing certificate/key failed, will generate a new one: %v", err) dnsNames = set.NewStrings() } else { dnsNames = set.NewStrings(serverCert.DNSNames...) } update := false requiredDNSNames := []string{"local", "juju-apiserver", "juju-mongodb"} for _, dnsName := range requiredDNSNames { if dnsNames.Contains(dnsName) { continue } dnsNames.Add(dnsName) update = true } if !update { return nil } // Write a new certificate to the mongo pem and agent config files. si.Cert, si.PrivateKey, err = cert.NewDefaultServer(config.CACert(), si.CAPrivateKey, dnsNames.Values()) if err != nil { return err } if err := mongo.UpdateSSLKey(config.DataDir(), si.Cert, si.PrivateKey); err != nil { return err } config.SetStateServingInfo(si) return nil }
func (sb *StubBacking) AllSpaces() ([]common.BackingSpace, error) { sb.MethodCall(sb, "AllSpaces") if err := sb.NextErr(); err != nil { return nil, err } // Filter duplicates. seen := set.Strings{} output := []common.BackingSpace{} for _, space := range sb.Spaces { if seen.Contains(space.Name()) { continue } seen.Add(space.Name()) output = append(output, space) } return output, nil }
func (sb *StubBacking) AllSubnets() ([]networkingcommon.BackingSubnet, error) { sb.MethodCall(sb, "AllSubnets") if err := sb.NextErr(); err != nil { return nil, err } // Filter duplicates. seen := set.Strings{} output := []networkingcommon.BackingSubnet{} for _, subnet := range sb.Subnets { if seen.Contains(subnet.CIDR()) { continue } seen.Add(subnet.CIDR()) output = append(output, subnet) } return output, nil }
func mergedAddresses(machineAddresses, providerAddresses []address) []network.Address { merged := make([]network.Address, 0, len(providerAddresses)+len(machineAddresses)) var providerValues set.Strings for _, address := range providerAddresses { // Older versions of Juju may have stored an empty address so ignore it here. if address.Value == "" { continue } providerValues.Add(address.Value) merged = append(merged, address.InstanceAddress()) } for _, address := range machineAddresses { if !providerValues.Contains(address.Value) { merged = append(merged, address.InstanceAddress()) } } return merged }
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 }