func getUsedCharms(model description.Model) set.Strings { result := set.NewStrings() for _, service := range model.Services() { result.Add(service.CharmURL()) } return result }
func getUsedTools(model description.Model) []params.SerializedModelTools { // Iterate through the model for all tools, and make a map of them. usedVersions := make(map[version.Binary]bool) // It is most likely that the preconditions will limit the number of // tools versions in use, but that is not relied on here. for _, machine := range model.Machines() { addToolsVersionForMachine(machine, usedVersions) } for _, application := range model.Applications() { for _, unit := range application.Units() { tools := unit.Tools() usedVersions[tools.Version()] = true } } out := make([]params.SerializedModelTools, 0, len(usedVersions)) for v := range usedVersions { out = append(out, params.SerializedModelTools{ Version: v.String(), URI: common.ToolsURL("", v), }) } return out }
func getUsedCharms(model description.Model) []string { result := set.NewStrings() for _, application := range model.Applications() { result.Add(application.CharmURL()) } return result.Values() }
func getUsedToolsVersions(model description.Model) map[version.Binary]bool { // Iterate through the model for all tools, and make a map of them. usedVersions := make(map[version.Binary]bool) // It is most likely that the preconditions will limit the number of // tools versions in use, but that is not depended on here. for _, machine := range model.Machines() { addToolsVersionForMachine(machine, usedVersions) } for _, service := range model.Services() { for _, unit := range service.Units() { tools := unit.Tools() usedVersions[tools.Version()] = true } } return usedVersions }
func updateConfigFromProvider(model description.Model, controllerConfig *config.Config) error { newConfig, err := config.New(config.NoDefaults, model.Config()) if err != nil { return errors.Trace(err) } provider, err := environs.New(newConfig) if err != nil { return errors.Trace(err) } updater, ok := provider.(environs.MigrationConfigUpdater) if !ok { return nil } model.UpdateConfig(updater.MigrationConfigUpdate(controllerConfig)) return nil }
// Import the database agnostic model representation into the database. func (st *State) Import(model description.Model) (_ *Model, _ *State, err error) { logger := loggo.GetLogger("juju.state.import-model") logger.Debugf("import starting for model %s", model.Tag().Id()) // At this stage, attempting to import a model with the same // UUID as an existing model will error. tag := model.Tag() _, err = st.GetModel(tag) if err == nil { // We have an existing matching model. return nil, nil, errors.AlreadyExistsf("model with UUID %s", tag.Id()) } else if !errors.IsNotFound(err) { return nil, nil, errors.Trace(err) } // Create the model. cfg, err := config.New(config.NoDefaults, model.Config()) if err != nil { return nil, nil, errors.Trace(err) } dbModel, newSt, err := st.NewModel(cfg, model.Owner()) if err != nil { return nil, nil, errors.Trace(err) } logger.Debugf("model created %s/%s", dbModel.Owner().Canonical(), dbModel.Name()) defer func() { if err != nil { newSt.Close() } }() // I would have loved to use import, but that is a reserved word. restore := importer{ st: newSt, dbModel: dbModel, model: model, logger: logger, } if err := restore.sequences(); err != nil { return nil, nil, errors.Annotate(err, "sequences") } // We need to import the sequences first as we may add blocks // in the modelExtras which will touch the block sequence. if err := restore.modelExtras(); err != nil { return nil, nil, errors.Annotate(err, "base model aspects") } if err := newSt.SetModelConstraints(restore.constraints(model.Constraints())); err != nil { return nil, nil, errors.Annotate(err, "model constraints") } if err := restore.modelUsers(); err != nil { return nil, nil, errors.Annotate(err, "modelUsers") } if err := restore.machines(); err != nil { return nil, nil, errors.Annotate(err, "machines") } if err := restore.services(); err != nil { return nil, nil, errors.Annotate(err, "services") } if err := restore.relations(); err != nil { return nil, nil, errors.Annotate(err, "relations") } // NOTE: at the end of the import make sure that the mode of the model // is set to "imported" not "active" (or whatever we call it). This way // we don't start model workers for it before the migration process // is complete. // Update the sequences to match that the source. logger.Debugf("import success") return dbModel, newSt, nil }
// Import the database agnostic model representation into the database. func (st *State) Import(model description.Model) (_ *Model, _ *State, err error) { logger := loggo.GetLogger("juju.state.import-model") logger.Debugf("import starting for model %s", model.Tag().Id()) // At this stage, attempting to import a model with the same // UUID as an existing model will error. tag := model.Tag() _, err = st.GetModel(tag) if err == nil { // We have an existing matching model. return nil, nil, errors.AlreadyExistsf("model with UUID %s", tag.Id()) } else if !errors.IsNotFound(err) { return nil, nil, errors.Trace(err) } // Create the model. cfg, err := config.New(config.NoDefaults, model.Config()) if err != nil { return nil, nil, errors.Trace(err) } dbModel, newSt, err := st.NewModel(ModelArgs{ CloudName: model.Cloud(), CloudRegion: model.CloudRegion(), Config: cfg, Owner: model.Owner(), MigrationMode: MigrationModeImporting, // NOTE(axw) we create the model without any storage // pools. We'll need to import the storage pools from // the model description before adding any volumes, // filesystems or storage instances. StorageProviderRegistry: storage.StaticProviderRegistry{}, }) if err != nil { return nil, nil, errors.Trace(err) } logger.Debugf("model created %s/%s", dbModel.Owner().Canonical(), dbModel.Name()) defer func() { if err != nil { newSt.Close() } }() // I would have loved to use import, but that is a reserved word. restore := importer{ st: newSt, dbModel: dbModel, model: model, logger: logger, } if err := restore.sequences(); err != nil { return nil, nil, errors.Annotate(err, "sequences") } // We need to import the sequences first as we may add blocks // in the modelExtras which will touch the block sequence. if err := restore.modelExtras(); err != nil { return nil, nil, errors.Annotate(err, "base model aspects") } if err := newSt.SetModelConstraints(restore.constraints(model.Constraints())); err != nil { return nil, nil, errors.Annotate(err, "model constraints") } if err := restore.sshHostKeys(); err != nil { return nil, nil, errors.Annotate(err, "sshHostKeys") } if err := restore.cloudimagemetadata(); err != nil { return nil, nil, errors.Annotate(err, "cloudimagemetadata") } if err := restore.actions(); err != nil { return nil, nil, errors.Annotate(err, "actions") } if err := restore.modelUsers(); err != nil { return nil, nil, errors.Annotate(err, "modelUsers") } if err := restore.machines(); err != nil { return nil, nil, errors.Annotate(err, "machines") } if err := restore.applications(); err != nil { return nil, nil, errors.Annotate(err, "applications") } if err := restore.relations(); err != nil { return nil, nil, errors.Annotate(err, "relations") } if err := restore.spaces(); err != nil { return nil, nil, errors.Annotate(err, "spaces") } if err := restore.linklayerdevices(); err != nil { return nil, nil, errors.Annotate(err, "linklayerdevices") } if err := restore.subnets(); err != nil { return nil, nil, errors.Annotate(err, "subnets") } if err := restore.ipaddresses(); err != nil { return nil, nil, errors.Annotate(err, "ipaddresses") } if err := restore.storage(); err != nil { return nil, nil, errors.Annotate(err, "storage") } // NOTE: at the end of the import make sure that the mode of the model // is set to "imported" not "active" (or whatever we call it). This way // we don't start model workers for it before the migration process // is complete. // Update the sequences to match that the source. logger.Debugf("import success") return dbModel, newSt, nil }