// SetInstanceInfo is used to provision a machine and in one steps set // it's instance id, nonce, hardware characteristics, add networks and // network interfaces as needed. // // TODO(dimitern) Do all the operations described in a single // transaction, rather than using separate calls. Alternatively, // we can add all the things to create/set in a document in some // collection and have a worker that takes care of the actual work. // Merge SetProvisioned() in here or drop it at that point. func (m *Machine) SetInstanceInfo( id instance.Id, nonce string, characteristics *instance.HardwareCharacteristics, networks []NetworkInfo, interfaces []NetworkInterfaceInfo) error { // Add the networks and interfaces first. for _, network := range networks { _, err := m.st.AddNetwork(network) if err != nil && errors.IsAlreadyExists(err) { // Ignore already existing networks. continue } else if err != nil { return err } } for _, iface := range interfaces { _, err := m.AddNetworkInterface(iface) if err != nil && errors.IsAlreadyExists(err) { // Ignore already existing network interfaces. continue } else if err != nil { return err } } return m.SetProvisioned(id, nonce, characteristics) }
// ServerError returns an error suitable for returning to an API // client, with an error code suitable for various kinds of errors // generated in packages outside the API. func ServerError(err error) *params.Error { if err == nil { return nil } code, ok := singletonCode(err) switch { case ok: case errors.IsUnauthorized(err): code = params.CodeUnauthorized case errors.IsNotFound(err): code = params.CodeNotFound case errors.IsAlreadyExists(err): code = params.CodeAlreadyExists case state.IsNotAssigned(err): code = params.CodeNotAssigned case state.IsHasAssignedUnitsError(err): code = params.CodeHasAssignedUnits case IsNoAddressSetError(err): code = params.CodeNoAddressSet case state.IsNotProvisionedError(err): code = params.CodeNotProvisioned default: code = params.ErrCode(err) } return ¶ms.Error{ Message: err.Error(), Code: code, } }