func (s *UploadSuite) TestPendingOkay(c *gc.C) { res, apiResult := newResourceResult(c, "a-service", "spam") uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) expected := uuid.String() s.response.Resource = apiResult.Resources[0] data := "<data>" fp, err := charmresource.GenerateFingerprint(strings.NewReader(data)) c.Assert(err, jc.ErrorIsNil) req, err := http.NewRequest("PUT", "/services/a-service/resources/spam", nil) c.Assert(err, jc.ErrorIsNil) req.Header.Set("Content-Type", "application/octet-stream") req.Header.Set("Content-SHA384", fp.String()) req.Header.Set("Content-Length", fmt.Sprint(len(data))) req.ContentLength = int64(len(data)) req.URL.RawQuery = "pendingid=" + expected reader := &stubFile{stub: s.stub} reader.returnRead = strings.NewReader(data) s.facade.pendingIDs = []string{expected} cl := client.NewClient(s.facade, s, s.facade) uploadID, err := cl.AddPendingResource("a-service", res[0].Resource, reader) c.Assert(err, jc.ErrorIsNil) s.stub.CheckCallNames(c, "FacadeCall", "Read", "Read", "Seek", "Do", ) s.stub.CheckCall(c, 4, "Do", req, reader, s.response) c.Check(uploadID, gc.Equals, expected) }
// mustUUID returns a stringified uuid or panics func mustUUID() string { uuid, err := utils.NewUUID() if err != nil { panic(err) } return uuid.String() }
// CharmArchiveName returns a string that is suitable as a file name // in a storage URL. It is constructed from the charm name, revision // and a random UUID string. func CharmArchiveName(name string, revision int) (string, error) { uuid, err := utils.NewUUID() if err != nil { return "", err } return charm.Quote(fmt.Sprintf("%s-%d-%s", name, revision, uuid)), nil }
func (task *provisionerTask) constructInstanceConfig( machine *apiprovisioner.Machine, auth authentication.AuthenticationProvider, pInfo *params.ProvisioningInfo, ) (*instancecfg.InstanceConfig, error) { stateInfo, apiInfo, err := auth.SetupAuthentication(machine) if err != nil { return nil, errors.Annotate(err, "failed to setup authentication") } // Generated a nonce for the new instance, with the format: "machine-#:UUID". // The first part is a badge, specifying the tag of the machine the provisioner // is running on, while the second part is a random UUID. uuid, err := utils.NewUUID() if err != nil { return nil, errors.Annotate(err, "failed to generate a nonce for machine "+machine.Id()) } nonce := fmt.Sprintf("%s:%s", task.machineTag, uuid) return instancecfg.NewInstanceConfig( machine.Id(), nonce, task.imageStream, pInfo.Series, task.secureServerConnection, nil, stateInfo, apiInfo, ) }
func (s *ModelSuite) TestNewModelSameUserSameNameFails(c *gc.C) { cfg, _ := s.createTestModelConfig(c) owner := s.Factory.MakeUser(c, nil).UserTag() // Create the first model. _, st1, err := s.State.NewModel(state.ModelArgs{ CloudName: "dummy", CloudRegion: "dummy-region", Config: cfg, Owner: owner, StorageProviderRegistry: storage.StaticProviderRegistry{}, }) c.Assert(err, jc.ErrorIsNil) defer st1.Close() // Attempt to create another model with a different UUID but the // same owner and name as the first. newUUID, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) cfg2 := testing.CustomModelConfig(c, testing.Attrs{ "name": cfg.Name(), "uuid": newUUID.String(), }) _, _, err = s.State.NewModel(state.ModelArgs{ CloudName: "dummy", CloudRegion: "dummy-region", Config: cfg2, Owner: owner, StorageProviderRegistry: storage.StaticProviderRegistry{}, }) errMsg := fmt.Sprintf("model %q for %s already exists", cfg2.Name(), owner.Canonical()) c.Assert(err, gc.ErrorMatches, errMsg) c.Assert(errors.IsAlreadyExists(err), jc.IsTrue) // Remove the first model. env1, err := st1.Model() c.Assert(err, jc.ErrorIsNil) err = env1.Destroy() c.Assert(err, jc.ErrorIsNil) // Destroy only sets the model to dying and RemoveAllModelDocs can // only be called on a dead model. Normally, the environ's lifecycle // would be set to dead after machines and services have been cleaned up. err = state.SetModelLifeDead(st1, env1.ModelTag().Id()) c.Assert(err, jc.ErrorIsNil) err = st1.RemoveAllModelDocs() c.Assert(err, jc.ErrorIsNil) // We should now be able to create the other model. env2, st2, err := s.State.NewModel(state.ModelArgs{ CloudName: "dummy", CloudRegion: "dummy-region", Config: cfg2, Owner: owner, StorageProviderRegistry: storage.StaticProviderRegistry{}, }) c.Assert(err, jc.ErrorIsNil) defer st2.Close() c.Assert(env2, gc.NotNil) c.Assert(st2, gc.NotNil) }
// NewLock returns a new lock with the given name within the given lock // directory, without acquiring it. The lock name must match the regular // expression defined by NameRegexp. func NewLock(lockDir, name string, cfg LockConfig) (*Lock, error) { if !validName.MatchString(name) { return nil, fmt.Errorf("Invalid lock name %q. Names must match %q", name, NameRegexp) } uuid, err := utils.NewUUID() if err != nil { return nil, err } lock := &Lock{ name: name, parent: lockDir, clock: cfg.Clock, nonce: uuid.String(), PID: os.Getpid(), stopWritingAliveFile: make(chan struct{}, 1), waitDelay: cfg.WaitDelay, lividityTimeout: cfg.LividityTimeout, readRetryTimeout: cfg.ReadRetryTimeout, sanityCheck: make(chan struct{}), } // Ensure the parent exists. if err := os.MkdirAll(lock.parent, 0755); err != nil { return nil, err } // Ensure that an old alive file doesn't exist. RemoveAll doesn't raise // an error if the target doesn't exist, so we don't expect any errors. if err := os.RemoveAll(lock.aliveFile(lock.PID)); err != nil { return nil, err } return lock, nil }
// newPendingID generates a new unique identifier for a resource. func newPendingID() (string, error) { uuid, err := utils.NewUUID() if err != nil { return "", errors.Annotate(err, "could not create new resource ID") } return uuid.String(), nil }
func testHandler(c *gc.C, batches chan<- wireformat.MetricBatch, statusMap StatusMap, gracePeriod time.Duration) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { c.Assert(r.Method, gc.Equals, "POST") dec := json.NewDecoder(r.Body) enc := json.NewEncoder(w) var incoming []wireformat.MetricBatch err := dec.Decode(&incoming) c.Assert(err, jc.ErrorIsNil) var resp = make(wireformat.EnvironmentResponses) for _, batch := range incoming { c.Logf("received metrics batch: %+v", batch) resp.Ack(batch.ModelUUID, batch.UUID) if statusMap != nil { unitName, status, info := statusMap(batch.UnitName) resp.SetStatus(batch.ModelUUID, unitName, status, info) } select { case batches <- batch: default: } } uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) err = enc.Encode(wireformat.Response{ UUID: uuid.String(), EnvResponses: resp, NewGracePeriod: gracePeriod, }) c.Assert(err, jc.ErrorIsNil) } }
func (s *EnvironSuite) TestNewEnvironmentSameUserSameNameFails(c *gc.C) { cfg, _ := s.createTestEnvConfig(c) owner := s.factory.MakeUser(c, nil).UserTag() // Create the first environment. _, st1, err := s.State.NewEnvironment(cfg, owner) c.Assert(err, jc.ErrorIsNil) defer st1.Close() // Attempt to create another environment with a different UUID but the // same owner and name as the first. newUUID, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) cfg2 := testing.CustomEnvironConfig(c, testing.Attrs{ "name": cfg.Name(), "uuid": newUUID.String(), }) _, _, err = s.State.NewEnvironment(cfg2, owner) errMsg := fmt.Sprintf("environment %q for %s already exists", cfg2.Name(), owner.Username()) c.Assert(err, gc.ErrorMatches, errMsg) c.Assert(errors.IsAlreadyExists(err), jc.IsTrue) // Remove the first environment. err = st1.RemoveAllEnvironDocs() c.Assert(err, jc.ErrorIsNil) // We should now be able to create the other environment. env2, st2, err := s.State.NewEnvironment(cfg2, owner) c.Assert(err, jc.ErrorIsNil) defer st2.Close() c.Assert(env2, gc.NotNil) c.Assert(st2, gc.NotNil) }
func (s *FlushContextSuite) TestRunHookRelationFlushingError(c *gc.C) { uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) ctx := s.getHookContext(c, uuid.String(), -1, "", noProxies) // Mess with multiple relation settings. relCtx0, ok := ctx.Relation(0) c.Assert(ok, jc.IsTrue) node0, err := relCtx0.Settings() c.Assert(err, jc.ErrorIsNil) node0.Set("foo", "1") relCtx1, ok := ctx.Relation(1) c.Assert(ok, jc.IsTrue) node1, err := relCtx1.Settings() c.Assert(err, jc.ErrorIsNil) node1.Set("bar", "2") // Flush the context with a failure. err = ctx.FlushContext("some badge", errors.New("blam pow")) c.Assert(err, gc.ErrorMatches, "blam pow") // Check that the changes have not been written to state. settings0, err := s.relunits[0].ReadSettings("u/0") c.Assert(err, jc.ErrorIsNil) c.Assert(settings0, gc.DeepEquals, map[string]interface{}{"relation-name": "db0"}) settings1, err := s.relunits[1].ReadSettings("u/0") c.Assert(err, jc.ErrorIsNil) c.Assert(settings1, gc.DeepEquals, map[string]interface{}{"relation-name": "db1"}) }
// charmArchiveStoragePath returns a string that is suitable as a // storage path, using a random UUID to avoid colliding with concurrent // uploads. func charmArchiveStoragePath(curl *charm.URL) (string, error) { uuid, err := utils.NewUUID() if err != nil { return "", err } return fmt.Sprintf("charms/%s-%s", curl.String(), uuid), nil }
func (s *ModelConfigSourceSuite) TestNewModelConfigForksControllerValue(c *gc.C) { uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) cfg := testing.CustomModelConfig(c, testing.Attrs{ "name": "another", "uuid": uuid.String(), }) owner := names.NewUserTag("test@remote") _, st, err := s.State.NewModel(state.ModelArgs{ Config: cfg, Owner: owner, CloudName: "dummy", CloudRegion: "nether-region", StorageProviderRegistry: storage.StaticProviderRegistry{}, }) c.Assert(err, jc.ErrorIsNil) defer st.Close() modelCfg, err := st.ModelConfig() c.Assert(err, jc.ErrorIsNil) c.Assert(modelCfg.AllAttrs()["apt-mirror"], gc.Equals, "http://mirror") // Change the local controller settings and ensure the model setting stays the same. localCloudSettings, err := s.State.ReadSettings(state.GlobalSettingsC, state.ControllerInheritedSettingsGlobalKey) c.Assert(err, jc.ErrorIsNil) localCloudSettings.Set("apt-mirror", "http://anothermirror") _, err = localCloudSettings.Write() c.Assert(err, jc.ErrorIsNil) modelCfg, err = st.ModelConfig() c.Assert(err, jc.ErrorIsNil) c.Assert(modelCfg.AllAttrs()["apt-mirror"], gc.Equals, "http://mirror") }
func (p manualProvider) PrepareForBootstrap(ctx environs.BootstrapContext, cfg *config.Config) (environs.Environ, error) { if _, ok := cfg.UnknownAttrs()["storage-auth-key"]; !ok { uuid, err := utils.NewUUID() if err != nil { return nil, err } cfg, err = cfg.Apply(map[string]interface{}{ "storage-auth-key": uuid.String(), }) if err != nil { return nil, err } } if use, ok := cfg.UnknownAttrs()["use-sshstorage"].(bool); ok && !use { return nil, fmt.Errorf("use-sshstorage must not be specified") } envConfig, err := p.validate(cfg, nil) if err != nil { return nil, err } cfg, err = cfg.Apply(envConfig.attrs) if err != nil { return nil, err } envConfig = newEnvironConfig(cfg, envConfig.attrs) if err := ensureBootstrapUbuntuUser(ctx, envConfig); err != nil { return nil, err } return p.open(envConfig) }
func newID() (string, error) { uuid, err := utils.NewUUID() if err != nil { return "", errors.Annotate(err, "could not create new payload ID") } return uuid.String(), nil }
func (s *RunHookSuite) TestRunHook(c *gc.C) { uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) for i, t := range runHookTests { c.Logf("\ntest %d: %s; perm %v", i, t.summary, t.spec.perm) ctx := s.getHookContext(c, uuid.String(), t.relid, t.remote, noProxies) paths := NewRealPaths(c) rnr := runner.NewRunner(ctx, paths) var hookExists bool if t.spec.perm != 0 { spec := t.spec spec.dir = "hooks" spec.name = hookName c.Logf("makeCharm %#v", spec) makeCharm(c, spec, paths.charm) hookExists = true } t0 := time.Now() err := rnr.RunHook("something-happened") if t.err == "" && hookExists { c.Assert(err, jc.ErrorIsNil) } else if !hookExists { c.Assert(runner.IsMissingHookError(err), jc.IsTrue) } else { c.Assert(err, gc.ErrorMatches, t.err) } if t.spec.background != "" && time.Now().Sub(t0) > 5*time.Second { c.Errorf("background process holding up hook execution") } } }
// MakeModel creates an model with specified params, // filling in sane defaults for missing values. If params is nil, // defaults are used for all values. // // By default the new model shares the same owner as the calling // Factory's model. func (factory *Factory) MakeModel(c *gc.C, params *ModelParams) *state.State { if params == nil { params = new(ModelParams) } if params.Name == "" { params.Name = uniqueString("testenv") } if params.Owner == nil { origEnv, err := factory.st.Model() c.Assert(err, jc.ErrorIsNil) params.Owner = origEnv.Owner() } // It only makes sense to make an model with the same provider // as the initial model, or things will break elsewhere. currentCfg, err := factory.st.ModelConfig() c.Assert(err, jc.ErrorIsNil) uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) cfg := testing.CustomModelConfig(c, testing.Attrs{ "name": params.Name, "uuid": uuid.String(), "type": currentCfg.Type(), "state-port": currentCfg.StatePort(), "api-port": currentCfg.APIPort(), }.Merge(params.ConfigAttrs)) _, st, err := factory.st.NewModel(state.ModelArgs{ Config: cfg, Owner: params.Owner.(names.UserTag), }) c.Assert(err, jc.ErrorIsNil) return st }
// Replace will do an atomic replacement of a symlink to a new path func Replace(link, newpath string) error { dstDir := filepath.Dir(link) uuid, err := utils.NewUUID() if err != nil { return err } randStr := uuid.String() tmpFile := filepath.Join(dstDir, "tmpfile"+randStr) // Create the new symlink before removing the old one. This way, if New() // fails, we still have a link to the old tools. err = New(newpath, tmpFile) if err != nil { return fmt.Errorf("cannot create symlink: %s", err) } // On Windows, symlinks may not be overwritten. We remove it first, // and then rename tmpFile if _, err := os.Stat(link); err == nil { err = os.RemoveAll(link) if err != nil { return err } } err = os.Rename(tmpFile, link) if err != nil { return fmt.Errorf("cannot update tools symlink: %v", err) } return nil }
func (s *PresenceSuite) SetUpSuite(c *gc.C) { s.BaseSuite.SetUpSuite(c) s.MgoSuite.SetUpSuite(c) uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) s.modelTag = names.NewModelTag(uuid.String()) }
// NewModelConfig returns a new model config given a base (controller) config // and a set of attributes that will be specific to the new model, overriding // any non-restricted attributes in the base configuration. The resulting // config will be suitable for creating a new model in state. // // If "attrs" does not include a UUID, a new, random one will be generated // and added to the config. // // The config will be validated with the provider before being returned. func (c ModelConfigCreator) NewModelConfig( isAdmin bool, base *config.Config, attrs map[string]interface{}, ) (*config.Config, error) { if err := c.checkVersion(base, attrs); err != nil { return nil, errors.Trace(err) } // Before comparing any values, we need to push the config through // the provider validation code. One of the reasons for this is that // numbers being serialized through JSON get turned into float64. The // schema code used in config will convert these back into integers. // However, before we can create a valid config, we need to make sure // we copy across fields from the main config that aren't there. baseAttrs := base.AllAttrs() restrictedFields, err := RestrictedProviderFields(base.Type()) if err != nil { return nil, errors.Trace(err) } for _, field := range restrictedFields { if _, ok := attrs[field]; !ok { if baseValue, ok := baseAttrs[field]; ok { attrs[field] = baseValue } } } // Generate a new UUID for the model as necessary, // and finalize the new config. if _, ok := attrs[config.UUIDKey]; !ok { uuid, err := utils.NewUUID() if err != nil { return nil, errors.Trace(err) } attrs[config.UUIDKey] = uuid.String() } cfg, err := finalizeConfig(isAdmin, base, attrs) if err != nil { return nil, errors.Trace(err) } attrs = cfg.AllAttrs() // Any values that would normally be copied from the controller // config can also be defined, but if they differ from the controller // values, an error is returned. for _, field := range restrictedFields { if value, ok := attrs[field]; ok { if serverValue := baseAttrs[field]; value != serverValue { return nil, errors.Errorf( "specified %s \"%v\" does not match controller \"%v\"", field, value, serverValue) } } } return cfg, nil }
// createTestEnvConfig returns a new model config and its UUID for testing. func (s *ModelSuite) createTestEnvConfig(c *gc.C) (*config.Config, string) { uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) return testing.CustomModelConfig(c, testing.Attrs{ "name": "testing", "uuid": uuid.String(), }), uuid.String() }
func (*uuidSuite) TestUUID(c *gc.C) { uuid, err := utils.NewUUID() c.Assert(err, gc.IsNil) uuidCopy := uuid.Copy() uuidRaw := uuid.Raw() uuidStr := uuid.String() c.Assert(uuidRaw, gc.HasLen, 16) c.Assert(uuidStr, jc.Satisfies, utils.IsValidUUIDString) uuid[0] = 0x00 uuidCopy[0] = 0xFF c.Assert(uuid, gc.Not(gc.DeepEquals), uuidCopy) uuidRaw[0] = 0xFF c.Assert(uuid, gc.Not(gc.DeepEquals), uuidRaw) nextUUID, err := utils.NewUUID() c.Assert(err, gc.IsNil) c.Assert(uuid, gc.Not(gc.DeepEquals), nextUUID) }
// migrateCharmStorage copies uploaded charms from provider storage // to environment storage, and then adds the storage path into the // charm's document in state. func migrateCharmStorage(st *state.State, agentConfig agent.Config) error { logger.Debugf("migrating charms to environment storage") charms, err := st.AllCharms() if err != nil { return err } storage := storage.NewStorage(st.EnvironUUID(), st.MongoSession()) // Local and manual provider host storage on the state server's // filesystem, and serve via HTTP storage. The storage worker // doesn't run yet, so we just open the files directly. fetchCharmArchive := fetchCharmArchive providerType := agentConfig.Value(agent.ProviderType) if providerType == provider.Local || provider.IsManual(providerType) { storageDir := agentConfig.Value(agent.StorageDir) fetchCharmArchive = localstorage{storageDir}.fetchCharmArchive } storagePaths := make(map[*charm.URL]string) for _, ch := range charms { if ch.IsPlaceholder() { logger.Debugf("skipping %s, placeholder charm", ch.URL()) continue } if !ch.IsUploaded() { logger.Debugf("skipping %s, not uploaded to provider storage", ch.URL()) continue } if charmStoragePath(ch) != "" { logger.Debugf("skipping %s, already in environment storage", ch.URL()) continue } url := charmBundleURL(ch) if url == nil { logger.Debugf("skipping %s, has no bundle URL", ch.URL()) continue } uuid, err := utils.NewUUID() if err != nil { return err } data, err := fetchCharmArchive(url) if err != nil { return err } curl := ch.URL() storagePath := fmt.Sprintf("charms/%s-%s", curl, uuid) logger.Debugf("uploading %s to %q in environment storage", curl, storagePath) err = storage.Put(storagePath, bytes.NewReader(data), int64(len(data))) if err != nil { return errors.Annotatef(err, "failed to upload %s to storage", curl) } storagePaths[curl] = storagePath } return stateAddCharmStoragePaths(st, storagePaths) }
func nameVolume(zone string) (string, error) { volumeUUID, err := utils.NewUUID() if err != nil { return "", errors.Annotate(err, "cannot generate uuid to name the volume") } // type-zone-uuid volumeName := fmt.Sprintf("%s--%s", zone, volumeUUID.String()) return volumeName, nil }
func (s *HookContextSuite) GetContext( c *gc.C, relId int, remoteName string, ) jujuc.Context { uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) return s.getHookContext( c, uuid.String(), relId, remoteName, noProxies, ) }
func (s *commonSuite) TestAuthFuncForTagKind(c *gc.C) { // TODO(dimitern): This list of all supported tags and kinds needs // to live in juju/names. uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) allTags := []names.Tag{ nil, // invalid tag names.NewActionTag(uuid.String()), names.NewCharmTag("cs:precise/missing"), names.NewModelTag(uuid.String()), names.NewFilesystemTag("20/20"), names.NewLocalUserTag("user"), names.NewMachineTag("42"), names.NewNetworkTag("public"), names.NewRelationTag("wordpress:mysql mysql:db"), names.NewServiceTag("wordpress"), names.NewSpaceTag("apps"), names.NewStorageTag("foo/42"), names.NewUnitTag("wordpress/5"), names.NewUserTag("joe"), names.NewVolumeTag("80/20"), } for i, allowedTag := range allTags { c.Logf("test #%d: allowedTag: %v", i, allowedTag) var allowedKind string if allowedTag != nil { allowedKind = allowedTag.Kind() } getAuthFunc := common.AuthFuncForTagKind(allowedKind) authFunc, err := getAuthFunc() if allowedKind == "" { c.Check(err, gc.ErrorMatches, "tag kind cannot be empty") c.Check(authFunc, gc.IsNil) continue } else if !c.Check(err, jc.ErrorIsNil) { continue } for j, givenTag := range allTags { c.Logf("test #%d.%d: givenTag: %v", i, j, givenTag) var givenKind string if givenTag != nil { givenKind = givenTag.Kind() } if allowedKind == givenKind { c.Check(authFunc(givenTag), jc.IsTrue) } else { c.Check(authFunc(givenTag), jc.IsFalse) } } } }
// addBackupMetadata stores metadata for a backup where it can be // accessed later. It returns a new ID that is associated with the // backup. If the provided metadata already has an ID set, it is // ignored. func addBackupMetadata(st *State, metadata *metadata.Metadata) (string, error) { // We use our own mongo _id value since the auto-generated one from // mongo may contain sensitive data (see bson.ObjectID). id, err := utils.NewUUID() if err != nil { return "", errors.Annotate(err, "error generating new ID") } idStr := id.String() return idStr, addBackupMetadataID(st, metadata, idStr) }
func (task *provisionerTask) constructInstanceConfig( machine *apiprovisioner.Machine, auth authentication.AuthenticationProvider, pInfo *params.ProvisioningInfo, ) (*instancecfg.InstanceConfig, error) { stateInfo, apiInfo, err := auth.SetupAuthentication(machine) if err != nil { return nil, errors.Annotate(err, "failed to setup authentication") } // Generated a nonce for the new instance, with the format: "machine-#:UUID". // The first part is a badge, specifying the tag of the machine the provisioner // is running on, while the second part is a random UUID. uuid, err := utils.NewUUID() if err != nil { return nil, errors.Annotate(err, "failed to generate a nonce for machine "+machine.Id()) } nonce := fmt.Sprintf("%s:%s", task.machineTag, uuid) instanceConfig, err := instancecfg.NewInstanceConfig( names.NewControllerTag(controller.Config(pInfo.ControllerConfig).ControllerUUID()), machine.Id(), nonce, task.imageStream, pInfo.Series, apiInfo, ) if err != nil { return nil, errors.Trace(err) } instanceConfig.Tags = pInfo.Tags if len(pInfo.Jobs) > 0 { instanceConfig.Jobs = pInfo.Jobs } if multiwatcher.AnyJobNeedsState(instanceConfig.Jobs...) { publicKey, err := simplestreams.UserPublicSigningKey() if err != nil { return nil, err } instanceConfig.Controller = &instancecfg.ControllerConfig{ PublicImageSigningKey: publicKey, MongoInfo: stateInfo, } instanceConfig.Controller.Config = make(map[string]interface{}) for k, v := range pInfo.ControllerConfig { instanceConfig.Controller.Config[k] = v } } return instanceConfig, nil }
// NewJSONMetricsRecorder creates a new JSON metrics recorder. // It checks if the metrics spool directory exists, if it does not - it is created. Then // it tries to find an unused metric batch UUID 3 times. func NewJSONMetricsRecorder(spoolDir string, charmURL string) (rec *JSONMetricsRecorder, rErr error) { lock, err := fslock.NewLock(spoolDir, spoolLockName) if err != nil { return nil, errors.Trace(err) } if err := lock.LockWithTimeout(lockTimeout, "initializing recorder"); err != nil { return nil, errors.Trace(err) } defer func() { err := lock.Unlock() if err != nil && rErr == nil { rErr = errors.Trace(err) rec = nil } else if err != nil { rErr = errors.Annotatef(err, "failed to unlock spool directory %q", spoolDir) } }() if err := checkSpoolDir(spoolDir); err != nil { return nil, errors.Trace(err) } mbUUID, err := utils.NewUUID() if err != nil { return nil, errors.Trace(err) } metaFile := filepath.Join(spoolDir, fmt.Sprintf("%s.meta", mbUUID.String())) dataFile := filepath.Join(spoolDir, mbUUID.String()) if _, err := os.Stat(metaFile); !os.IsNotExist(err) { if err != nil { return nil, errors.Annotatef(err, "failed to stat file %s", metaFile) } return nil, errors.Errorf("file %s already exists", metaFile) } if _, err := os.Stat(dataFile); err != nil && !os.IsNotExist(err) { if err != nil { return nil, errors.Annotatef(err, "failed to stat file %s", dataFile) } return nil, errors.Errorf("file %s already exists", dataFile) } if err := recordMetaData(metaFile, charmURL, mbUUID.String()); err != nil { return nil, errors.Trace(err) } recorder := &JSONMetricsRecorder{ path: dataFile, } if err := recorder.open(); err != nil { return nil, errors.Trace(err) } return recorder, nil }
// PrepareForCreateEnvironment is specified in the EnvironProvider interface. func (p environProvider) PrepareForCreateEnvironment(cfg *config.Config) (*config.Config, error) { attrs := cfg.UnknownAttrs() if _, ok := attrs["control-bucket"]; !ok { uuid, err := utils.NewUUID() if err != nil { return nil, errors.Trace(err) } attrs["control-bucket"] = fmt.Sprintf("%x", uuid.Raw()) } return cfg.Apply(attrs) }
func createTestModelConfig(c *gc.C, controllerUUID string) (*config.Config, string) { uuid, err := utils.NewUUID() c.Assert(err, jc.ErrorIsNil) if controllerUUID == "" { controllerUUID = uuid.String() } return testing.CustomModelConfig(c, testing.Attrs{ "name": "testing", "uuid": uuid.String(), }), uuid.String() }