// AddNetwork creates a new network with the given params. If a // network with the same name or provider id already exists in state, // an error satisfying errors.IsAlreadyExists is returned. func (st *State) AddNetwork(args NetworkInfo) (n *Network, err error) { defer errors.Contextf(&err, "cannot add network %q", args.Name) if args.CIDR != "" { _, _, err := net.ParseCIDR(args.CIDR) if err != nil { return nil, err } } if args.Name == "" { return nil, fmt.Errorf("name must be not empty") } if !names.IsValidNetwork(args.Name) { return nil, fmt.Errorf("invalid name") } if args.ProviderId == "" { return nil, fmt.Errorf("provider id must be not empty") } if args.VLANTag < 0 || args.VLANTag > 4094 { return nil, fmt.Errorf("invalid VLAN tag %d: must be between 0 and 4094", args.VLANTag) } doc := newNetworkDoc(args) ops := []txn.Op{{ C: st.networks.Name, Id: args.Name, Assert: txn.DocMissing, Insert: doc, }} err = st.runTransaction(ops) switch err { case txn.ErrAborted: if _, err = st.Network(args.Name); err == nil { return nil, errors.AlreadyExistsf("network %q", args.Name) } else if err != nil { return nil, err } case nil: // We have a unique key restriction on the ProviderId field, // which will cause the insert to fail if there is another // record with the same provider id in the table. The txn // logic does not report insertion errors, so we check that // the record has actually been inserted correctly before // reporting success. if _, err = st.Network(args.Name); err != nil { return nil, errors.AlreadyExistsf("network with provider id %q", args.ProviderId) } return newNetwork(st, doc), nil } return nil, err }
// CreateSettings is part of the SettingsManager interface. func (m MemSettings) CreateSettings(key string, settings map[string]interface{}) error { if _, ok := m.Settings[key]; ok { return errors.AlreadyExistsf("settings with key %q", key) } m.Settings[key] = settings return nil }
// AddModelUser adds a new user to the database. func (st *State) AddModelUser(spec ModelUserSpec) (*ModelUser, error) { // Ensure local user exists in state before adding them as an model user. if spec.User.IsLocal() { localUser, err := st.User(spec.User) if err != nil { return nil, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", spec.User.Name())) } if spec.DisplayName == "" { spec.DisplayName = localUser.DisplayName() } } // Ensure local createdBy user exists. if spec.CreatedBy.IsLocal() { if _, err := st.User(spec.CreatedBy); err != nil { return nil, errors.Annotatef(err, "createdBy user %q does not exist locally", spec.CreatedBy.Name()) } } modelUUID := st.ModelUUID() op := createModelUserOp(modelUUID, spec.User, spec.CreatedBy, spec.DisplayName, spec.ReadOnly) err := st.runTransaction([]txn.Op{op}) if err == txn.ErrAborted { err = errors.AlreadyExistsf("model user %q", spec.User.Canonical()) } if err != nil { return nil, errors.Trace(err) } // Re-read from DB to get the multi-env updated values. return st.ModelUser(spec.User) }
// UpdateAccount implements AccountUpdater. func (c *MemStore) UpdateAccount(controllerName, accountName string, details jujuclient.AccountDetails) error { if err := jujuclient.ValidateControllerName(controllerName); err != nil { return err } if err := jujuclient.ValidateAccountName(accountName); err != nil { return err } if err := jujuclient.ValidateAccountDetails(details); err != nil { return err } accounts, ok := c.Accounts[controllerName] if !ok { accounts = &jujuclient.ControllerAccounts{ Accounts: make(map[string]jujuclient.AccountDetails), } c.Accounts[controllerName] = accounts } if len(accounts.Accounts) > 0 { if _, ok := accounts.Accounts[accountName]; !ok { return errors.AlreadyExistsf( "alternative account for controller %s", controllerName, ) } } accounts.Accounts[accountName] = details return nil }
func (s *Service) start() error { installed, err := s.Installed() if err != nil { return errors.Trace(err) } if !installed { return errors.NotFoundf("application " + s.Service.Name) } running, err := s.Running() if err != nil { return errors.Trace(err) } if running { return errors.AlreadyExistsf("running service %s", s.Service.Name) } conn, err := s.newConn() if err != nil { return errors.Trace(err) } defer conn.Close() statusCh := newChan() _, err = conn.StartUnit(s.UnitName, "fail", statusCh) if err != nil { return s.errorf(err, "dbus start request failed") } if err := s.wait("start", statusCh); err != nil { return errors.Trace(err) } return nil }
// Add the named component factory func to the registry. func RegisterComponentFunc(name string, f ComponentFunc) error { if _, ok := registeredComponentFuncs[name]; ok { return errors.AlreadyExistsf("%s", name) } registeredComponentFuncs[name] = f return nil }
// Create makes a new Admin account with a given email and pwhash. func Create(d db.DB, email, pwhash string) (util.Key, error) { var none util.Key adminJSON, err := db.GetByKey(d, emails, []byte(email)) switch { case err != nil: return none, err case len(adminJSON) != 0: return none, errors.AlreadyExistsf("admin for email %s:", email) } hash, salt := util.HashedAndSalt(pwhash, time.Now().String()) seed := time.Now().String() key := util.SaltedHash(string(hash), seed) adm := &Admin{ Email: email, Salt: salt, Hash: hash, Key: key, } if err := db.StoreKeyValue(d, admins, []byte(key), adm); err != nil { return none, err } return key, db.StoreKeyValue(d, emails, []byte(email), adm) }
// AddCharm adds the ch charm with curl to the state. // On success the newly added charm state is returned. func (st *State) AddCharm(info CharmInfo) (stch *Charm, err error) { charms, closer := st.getCollection(charmsC) defer closer() if err := validateCharmVersion(info.Charm); err != nil { return nil, errors.Trace(err) } query := charms.FindId(info.ID.String()).Select(bson.D{{"placeholder", 1}}) buildTxn := func(attempt int) ([]txn.Op, error) { var placeholderDoc struct { Placeholder bool `bson:"placeholder"` } if err := query.One(&placeholderDoc); err == mgo.ErrNotFound { return insertCharmOps(st, info) } else if err != nil { return nil, errors.Trace(err) } else if placeholderDoc.Placeholder { return updateCharmOps(st, info, stillPlaceholder) } return nil, errors.AlreadyExistsf("charm %q", info.ID) } if err = st.run(buildTxn); err == nil { return st.Charm(info.ID) } return nil, errors.Trace(err) }
// Track adds records for the payload to persistence. If the payload // is already there then false gets returned (true if inserted). // Existing records are not checked for consistency. func (pp Persistence) Track(id string, pl payload.Payload) (bool, error) { logger.Tracef("insertng %#v", pl) _, err := pp.LookUp(pl.Name, pl.ID) if err == nil { return false, errors.AlreadyExistsf("payload for %q", pl.FullID()) } else if !errors.IsNotFound(err) { return false, errors.Annotate(err, "while checking for collisions") } // TODO(ericsnow) There is a *slight* race here. I haven't found // a simple way to check the secondary key in the transaction. var okay bool var ops []txn.Op // TODO(ericsnow) Add unitPersistence.newEnsureAliveOp(pp.unit)? ops = append(ops, pp.newInsertPayloadOps(id, pl)...) buildTxn := func(attempt int) ([]txn.Op, error) { if attempt > 0 { okay = false return nil, jujutxn.ErrNoOperations } okay = true return ops, nil } if err := pp.st.Run(buildTxn); err != nil { return false, errors.Trace(err) } return okay, nil }
//Add a queue by name func (m *Metadata) AddQueue(queue string) error { mutex := zk.NewLock(m.zkClient.Conn, m.operationPath, zk.WorldACL(zk.PermAll)) if err := mutex.Lock(); err != nil { return errors.Trace(err) } defer mutex.Unlock() if err := m.RefreshMetadata(); err != nil { return errors.Trace(err) } if exist := m.ExistQueue(queue); exist { return errors.AlreadyExistsf("CreateQueue queue:%s ", queue) } if err := m.manager.CreateTopic(queue, int32(m.config.KafkaReplications), int32(m.config.KafkaPartitions)); err != nil { return errors.Trace(err) } path := m.buildQueuePath(queue) data := "" log.Debugf("add queue, zk path:%s, data:%s", path, data) if err := m.zkClient.CreateRec(path, data, 0); err != nil { return errors.Trace(err) } return nil }
func (m *Metadata) AddGroupConfig(group string, queue string, write bool, read bool, url string, ips []string) error { mutex := zk.NewLock(m.zkClient.Conn, m.operationPath, zk.WorldACL(zk.PermAll)) if err := mutex.Lock(); err != nil { return errors.Trace(err) } defer mutex.Unlock() if err := m.RefreshMetadata(); err != nil { return errors.Trace(err) } if exist := m.ExistGroup(queue, group); exist { return errors.AlreadyExistsf("queue : %q, group : %q", queue, group) } path := m.buildConfigPath(group, queue) groupConfig := GroupConfig{ Group: group, Queue: queue, Write: write, Read: read, Url: url, Ips: ips, } data := groupConfig.String() log.Debugf("add group config, zk path:%s, data:%s", path, data) if err := m.zkClient.CreateRec(path, data, 0); err != nil { return errors.Trace(err) } return nil }
func (i *importer) addSubnet(args SubnetInfo) error { buildTxn := func(attempt int) ([]txn.Op, error) { subnet, err := i.st.newSubnetFromArgs(args) if err != nil { return nil, errors.Trace(err) } ops := i.st.addSubnetOps(args) if attempt != 0 { if _, err = i.st.Subnet(args.CIDR); err == nil { return nil, errors.AlreadyExistsf("subnet %q", args.CIDR) } if err := subnet.Refresh(); err != nil { if errors.IsNotFound(err) { return nil, errors.Errorf("ProviderId %q not unique", args.ProviderId) } return nil, errors.Trace(err) } } return ops, nil } err := i.st.run(buildTxn) if err != nil { return errors.Trace(err) } return nil }
// AddSubnet creates and returns a new subnet func (st *State) AddSubnet(args SubnetInfo) (subnet *Subnet, err error) { defer errors.DeferredAnnotatef(&err, "adding subnet %q", args.CIDR) subnet, err = st.newSubnetFromArgs(args) if err != nil { return nil, errors.Trace(err) } ops := st.addSubnetOps(args) ops = append(ops, assertModelActiveOp(st.ModelUUID())) buildTxn := func(attempt int) ([]txn.Op, error) { if attempt != 0 { if err := checkModelActive(st); err != nil { return nil, errors.Trace(err) } if _, err = st.Subnet(args.CIDR); err == nil { return nil, errors.AlreadyExistsf("subnet %q", args.CIDR) } if err := subnet.Refresh(); err != nil { if errors.IsNotFound(err) { return nil, errors.Errorf("ProviderId %q not unique", args.ProviderId) } return nil, errors.Trace(err) } } return ops, nil } err = st.run(buildTxn) if err != nil { return nil, errors.Trace(err) } return subnet, nil }
// AddEnvironmentUser adds a new user to the database. func (st *State) AddEnvironmentUser(user, createdBy names.UserTag, displayName string) (*EnvironmentUser, error) { // Ensure local user exists in state before adding them as an environment user. if user.IsLocal() { localUser, err := st.User(user) if err != nil { return nil, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", user.Name())) } if displayName == "" { displayName = localUser.DisplayName() } } // Ensure local createdBy user exists. if createdBy.IsLocal() { if _, err := st.User(createdBy); err != nil { return nil, errors.Annotate(err, fmt.Sprintf("createdBy user %q does not exist locally", createdBy.Name())) } } envuuid := st.EnvironUUID() op, doc := createEnvUserOpAndDoc(envuuid, user, createdBy, displayName) err := st.runTransaction([]txn.Op{op}) if err == txn.ErrAborted { err = errors.AlreadyExistsf("environment user %q", user.Username()) } if err != nil { return nil, errors.Trace(err) } return &EnvironmentUser{st: st, doc: *doc}, nil }
// NewModel creates a new model with its own UUID and // prepares it for use. Model and State instances for the new // model are returned. // // The controller model's UUID is attached to the new // model's document. Having the server UUIDs stored with each // model document means that we have a way to represent external // models, perhaps for future use around cross model // relations. func (st *State) NewModel(cfg *config.Config, owner names.UserTag) (_ *Model, _ *State, err error) { if owner.IsLocal() { if _, err := st.User(owner); err != nil { return nil, nil, errors.Annotate(err, "cannot create model") } } ssEnv, err := st.ControllerModel() if err != nil { return nil, nil, errors.Annotate(err, "could not load controller model") } uuid := cfg.UUID() newState, err := st.ForModel(names.NewModelTag(uuid)) if err != nil { return nil, nil, errors.Annotate(err, "could not create state for new model") } defer func() { if err != nil { newState.Close() } }() ops, err := newState.envSetupOps(cfg, uuid, ssEnv.UUID(), owner) if err != nil { return nil, nil, errors.Annotate(err, "failed to create new model") } err = newState.runTransaction(ops) if err == txn.ErrAborted { // We have a unique key restriction on the "owner" and "name" fields, // which will cause the insert to fail if there is another record with // the same "owner" and "name" in the collection. If the txn is // aborted, check if it is due to the unique key restriction. models, closer := st.getCollection(modelsC) defer closer() envCount, countErr := models.Find(bson.D{ {"owner", owner.Canonical()}, {"name", cfg.Name()}}, ).Count() if countErr != nil { err = errors.Trace(countErr) } else if envCount > 0 { err = errors.AlreadyExistsf("model %q for %s", cfg.Name(), owner.Canonical()) } else { err = errors.New("model already exists") } } if err != nil { return nil, nil, errors.Trace(err) } newEnv, err := newState.Model() if err != nil { return nil, nil, errors.Trace(err) } return newEnv, newState, nil }
// RegisterNewCommand will add a command for got to handle when called. func RegisterNewCommand(name string, constructor CommandConstructor) error { existing, ok := registry[name] if ok { return errors.AlreadyExistsf("command %q already registered for %v", name, existing) } registry[name] = constructor return nil }
// AddSpace creates and returns a new space. func (st *State) AddSpace(name string, providerId network.Id, subnets []string, isPublic bool) (newSpace *Space, err error) { defer errors.DeferredAnnotatef(&err, "adding space %q", name) if !names.IsValidSpace(name) { return nil, errors.NewNotValid(nil, "invalid space name") } spaceDoc := spaceDoc{ Life: Alive, Name: name, IsPublic: isPublic, ProviderId: string(providerId), } newSpace = &Space{doc: spaceDoc, st: st} ops := []txn.Op{{ C: spacesC, Id: name, Assert: txn.DocMissing, Insert: spaceDoc, }} if providerId != "" { ops = append(ops, st.networkEntityGlobalKeyOp("space", providerId)) } for _, subnetId := range subnets { // TODO:(mfoord) once we have refcounting for subnets we should // also assert that the refcount is zero as moving the space of a // subnet in use is not permitted. ops = append(ops, txn.Op{ C: subnetsC, Id: subnetId, Assert: txn.DocExists, Update: bson.D{{"$set", bson.D{{"space-name", name}}}}, }) } if err := st.runTransaction(ops); err == txn.ErrAborted { if _, err := st.Space(name); err == nil { return nil, errors.AlreadyExistsf("space %q", name) } for _, subnetId := range subnets { if _, err := st.Subnet(subnetId); errors.IsNotFound(err) { return nil, err } } if err := newSpace.Refresh(); err != nil { if errors.IsNotFound(err) { return nil, errors.Errorf("ProviderId %q not unique", providerId) } return nil, errors.Trace(err) } return nil, errors.Trace(err) } else if err != nil { return nil, err } return newSpace, nil }
func (s *SpacesSuite) TestAddSpacesAPIError(c *gc.C) { apiservertesting.SharedStub.SetErrors(errors.AlreadyExistsf("space-foo")) p := checkAddSpacesParams{ Name: "foo", Subnets: []string{"10.0.0.0/24"}, MakesCall: true, Error: "space-foo already exists", } s.checkAddSpaces(c, p) }
func (m *Metadata) RegisterService(id int, data string) error { err := m.zkClient.Create(fmt.Sprintf("%s/%d", m.servicePath, id), data, zk.FlagEphemeral) if err != nil { if err == zk.ErrNodeExists { return errors.AlreadyExistsf("service %d", id) } return errors.Trace(err) } return nil }
// addIPAddress implements the State method to add an IP address. func addIPAddress(st *State, addr network.Address, subnetid string) (ipaddress *IPAddress, err error) { defer errors.DeferredAnnotatef(&err, "cannot add IP address %q", addr) // This checks for a missing value as well as invalid values ip := net.ParseIP(addr.Value) if ip == nil { return nil, errors.NotValidf("address") } // Generate the UUID for the new IP address. uuid, err := utils.NewUUID() if err != nil { return nil, err } addressID := st.docID(addr.Value) ipDoc := ipaddressDoc{ DocID: addressID, ModelUUID: st.ModelUUID(), UUID: uuid.String(), Life: Alive, State: AddressStateUnknown, SubnetId: subnetid, Value: addr.Value, Type: string(addr.Type), Scope: string(addr.Scope), SpaceName: string(addr.SpaceName), } ipaddress = &IPAddress{doc: ipDoc, st: st} ops := []txn.Op{ assertModelAliveOp(st.ModelUUID()), { C: ipaddressesC, Id: addressID, Assert: txn.DocMissing, Insert: ipDoc, }, } err = st.runTransaction(ops) switch err { case txn.ErrAborted: if err := checkModeLife(st); err != nil { return nil, errors.Trace(err) } if _, err = st.IPAddress(addr.Value); err == nil { return nil, errors.AlreadyExistsf("address") } case nil: return ipaddress, nil } return nil, errors.Trace(err) }
// addBsonDField adds a new field to the end of a bson.D, returning // the updated bson.D. func addBsonDField(d bson.D, name string, value interface{}) (bson.D, error) { for i := range d { if d[i].Name == name { return nil, errors.AlreadyExistsf("field %q", name) } } return append(d, bson.DocElem{ Name: name, Value: value, }), nil }
func (st *State) addUserAccess(spec UserAccessSpec, target userAccessTarget) (permission.UserAccess, error) { // Ensure local user exists in state before adding them as an model user. if spec.User.IsLocal() { localUser, err := st.User(spec.User) if err != nil { return permission.UserAccess{}, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", spec.User.Name())) } if spec.DisplayName == "" { spec.DisplayName = localUser.DisplayName() } } // Ensure local createdBy user exists. if spec.CreatedBy.IsLocal() { if _, err := st.User(spec.CreatedBy); err != nil { return permission.UserAccess{}, errors.Annotatef(err, "createdBy user %q does not exist locally", spec.CreatedBy.Name()) } } var ( ops []txn.Op err error targetTag names.Tag ) switch target.globalKey { case modelGlobalKey: ops = createModelUserOps( target.uuid, spec.User, spec.CreatedBy, spec.DisplayName, st.NowToTheSecond(), spec.Access) targetTag = names.NewModelTag(target.uuid) case controllerGlobalKey: ops = createControllerUserOps( st.ControllerUUID(), spec.User, spec.CreatedBy, spec.DisplayName, st.NowToTheSecond(), spec.Access) targetTag = st.controllerTag default: return permission.UserAccess{}, errors.NotSupportedf("user access global key %q", target.globalKey) } err = st.runTransactionFor(target.uuid, ops) if err == txn.ErrAborted { err = errors.AlreadyExistsf("user access %q", spec.User.Id()) } if err != nil { return permission.UserAccess{}, errors.Trace(err) } return st.UserAccess(spec.User, targetTag) }
func (m *Manager) createOrUpdateTopicPartitionAssignmentPathInZK(topic string, assignment partitonAssignment, update bool) error { topicPath := fmt.Sprintf("%s%s/%s", m.kafkaRoot, brokerTopics, topic) if !update { exist, _, err := m.zkClient.Exists(topicPath) if err != nil { return errors.Trace(err) } if exist { return errors.AlreadyExistsf("topic : %q", topic) } // 由于命令接口前段对queue名称进行了限制,所以暂时不需要下面这几步校验 // topics, err := m.client.Topics() // if err != nil { // return errors.Trace(err) // } // for _, noTopic := range topics { // if strings.Replace(topic, ".", "_", -1) == strings.Replace(noTopic, ".", "_", -1) { // return errors.NotValidf("topic : %q", topic) // } // } info := &topicInfo{Version: defaultVersion} topicConfigPath := fmt.Sprintf("%s%s/%s", m.kafkaRoot, topicConfigs, topic) configData, err := json.Marshal(&info) if err != nil { return errors.Trace(err) } err = m.zkClient.Create(topicConfigPath, string(configData), 0) if err != nil { return errors.Trace(err) } } partitionConfig := topicPatitionConfig{ Version: defaultVersion, Partitions: assignment, } partitionConfigData, err := json.Marshal(&partitionConfig) if err != nil { return errors.Trace(err) } if update { err = m.zkClient.Set(topicPath, string(partitionConfigData)) if err != nil { return errors.Trace(err) } } else { err = m.zkClient.Create(topicPath, string(partitionConfigData), 0) if err != nil { return errors.Trace(err) } } return nil }
func (st *State) addUser(name, displayName, password, creator string, secretKey []byte) (*User, error) { if !names.IsValidUserName(name) { return nil, errors.Errorf("invalid user name %q", name) } nameToLower := strings.ToLower(name) dateCreated := st.NowToTheSecond() user := &User{ st: st, doc: userDoc{ DocID: nameToLower, Name: name, DisplayName: displayName, SecretKey: secretKey, CreatedBy: creator, DateCreated: dateCreated, }, } if password != "" { salt, err := utils.RandomSalt() if err != nil { return nil, err } user.doc.PasswordHash = utils.UserPasswordHash(password, salt) user.doc.PasswordSalt = salt } ops := []txn.Op{{ C: usersC, Id: nameToLower, Assert: txn.DocMissing, Insert: &user.doc, }} controllerUserOps := createControllerUserOps(st.ControllerUUID(), names.NewUserTag(name), names.NewUserTag(creator), displayName, dateCreated, defaultControllerPermission) ops = append(ops, controllerUserOps...) err := st.runTransaction(ops) if err == txn.ErrAborted { err = errors.AlreadyExistsf("user") } if err != nil { return nil, errors.Trace(err) } return user, nil }
func (s *CreateSuite) TestRunWithExistingSubnetFails(c *gc.C) { s.api.SetErrors(nil, errors.AlreadyExistsf("subnet %q", "10.10.0.0/24")) err := s.AssertRunFails(c, `cannot create subnet "10.10.0.0/24": subnet "10.10.0.0/24" already exists`, "10.10.0.0/24", "space", "zone1", ) c.Assert(err, jc.Satisfies, errors.IsAlreadyExists) s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close") s.api.CheckCall(c, 1, "CreateSubnet", names.NewSubnetTag("10.10.0.0/24"), names.NewSpaceTag("space"), s.Strings("zone1"), false, ) }
// UpdateAccount implements AccountUpdater. func (s *store) UpdateAccount(controllerName, accountName string, details AccountDetails) error { if err := ValidateControllerName(controllerName); err != nil { return errors.Trace(err) } if err := ValidateAccountName(accountName); err != nil { return errors.Trace(err) } if err := ValidateAccountDetails(details); err != nil { return errors.Trace(err) } lock, err := s.lock("update-account") if err != nil { return errors.Trace(err) } defer s.unlock(lock) controllerAccounts, err := ReadAccountsFile(JujuAccountsPath()) if err != nil { return errors.Trace(err) } if controllerAccounts == nil { controllerAccounts = make(map[string]*ControllerAccounts) } accounts, ok := controllerAccounts[controllerName] if !ok { accounts = &ControllerAccounts{ Accounts: make(map[string]AccountDetails), } controllerAccounts[controllerName] = accounts } if oldDetails, ok := accounts.Accounts[accountName]; ok && details == oldDetails { return nil } // NOTE(axw) it is currently not valid for a client to have multiple // logins for a controller. We may relax this in the future, but for // now we are strict. if len(accounts.Accounts) > 0 { if _, ok := accounts.Accounts[accountName]; !ok { return errors.AlreadyExistsf( "alternative account for controller %s", controllerName, ) } } accounts.Accounts[accountName] = details return errors.Trace(WriteAccountsFile(controllerAccounts)) }
// AddController implements ControllerUpdater. func (s *store) AddController(name string, details ControllerDetails) error { if err := ValidateControllerName(name); err != nil { return errors.Trace(err) } if err := ValidateControllerDetails(details); err != nil { return errors.Trace(err) } releaser, err := s.acquireLock() if err != nil { return errors.Annotatef(err, "cannot add controller %v", name) } defer releaser.Release() all, err := ReadControllersFile(JujuControllersPath()) if err != nil { return errors.Annotate(err, "cannot get controllers") } if len(all.Controllers) == 0 { all.Controllers = make(map[string]ControllerDetails) } if _, ok := all.Controllers[name]; ok { return errors.AlreadyExistsf("controller with name %s", name) } for k, v := range all.Controllers { if v.ControllerUUID == details.ControllerUUID { return errors.AlreadyExistsf("controller with UUID %s (%s)", details.ControllerUUID, k) } } all.Controllers[name] = details return WriteControllersFile(all) }
// AddSpace creates and returns a new space. func (st *State) AddSpace(name string, subnets []string, isPublic bool) (newSpace *Space, err error) { defer errors.DeferredAnnotatef(&err, "adding space %q", name) if !names.IsValidSpace(name) { return nil, errors.NewNotValid(nil, "invalid space name") } spaceID := st.docID(name) spaceDoc := spaceDoc{ DocID: spaceID, EnvUUID: st.EnvironUUID(), Life: Alive, Name: name, IsPublic: isPublic, } newSpace = &Space{doc: spaceDoc, st: st} ops := []txn.Op{{ C: spacesC, Id: spaceID, Assert: txn.DocMissing, Insert: spaceDoc, }} for _, subnetId := range subnets { // TODO:(mfoord) once we have refcounting for subnets we should // also assert that the refcount is zero as moving the space of a // subnet in use is not permitted. ops = append(ops, txn.Op{ C: subnetsC, Id: st.docID(subnetId), Assert: txn.DocExists, Update: bson.D{{"$set", bson.D{{"space-name", name}}}}, }) } if err := st.runTransaction(ops); err == txn.ErrAborted { if _, err := st.Space(name); err == nil { return nil, errors.AlreadyExistsf("space %q", name) } for _, subnetId := range subnets { if _, err := st.Subnet(subnetId); errors.IsNotFound(err) { return nil, err } } } else if err != nil { return nil, err } return newSpace, nil }
func (s *Service) install() error { installed, err := s.Installed() if err != nil { return errors.Trace(err) } if installed { same, err := s.check() if err != nil { return errors.Trace(err) } if same { return errors.AlreadyExistsf("service %s", s.Service.Name) } // An old copy is already running so stop it first. if err := s.Stop(); err != nil { return errors.Annotate(err, "systemd: could not stop old service") } if err := s.Remove(); err != nil { return errors.Annotate(err, "systemd: could not remove old service") } } filename, err := s.writeConf() if err != nil { return errors.Trace(err) } conn, err := s.newConn() if err != nil { return errors.Trace(err) } defer conn.Close() runtime, force := false, true _, err = conn.LinkUnitFiles([]string{filename}, runtime, force) if err != nil { return s.errorf(err, "dbus link request failed") } if err := conn.Reload(); err != nil { return s.errorf(err, "dbus post-link daemon reload request failed") } _, _, err = conn.EnableUnitFiles([]string{filename}, runtime, force) if err != nil { return s.errorf(err, "dbus enable request failed") } return nil }
func (s *SpacesSuite) TestAddSpacesAPIError(c *gc.C) { apiservertesting.SharedStub.SetErrors( nil, // Backing.EnvironConfig() nil, // Provider.Open() nil, // ZonedNetworkingEnviron.SupportsSpaces() errors.AlreadyExistsf("space-foo"), // Backing.AddSpace() ) p := checkAddSpacesParams{ Name: "foo", Subnets: []string{"10.0.0.0/24"}, MakesCall: true, Error: "space-foo already exists", } s.checkAddSpaces(c, p) }