// validateMigrationStepSystem checks the validity of the state transitions of a possible migration step
// on the system channel.
961761
func validateMigrationStepSystem(oldType, newType string, oldState, newState ab.ConsensusType_MigrationState, newContext uint64) error {
	// Check validity of new state, type, and context
	unExpCtx := "Consensus-type migration, state=%s, unexpected context, actual=%d (expected=%s)"
	unExpType := "Consensus-type migration, state=%s, unexpected type, actual=%s (expected=%s)"
	switch newState {
	case ab.ConsensusType_MIG_STATE_NONE:
		if newContext != 0 {
			return errors.Errorf(unExpCtx, newState, newContext, "0")
		}
	case ab.ConsensusType_MIG_STATE_START:
		if newType != "kafka" {
			return errors.Errorf(unExpType, newState, newType, "kafka")
		}
		if newContext != 0 {
			return errors.Errorf(unExpCtx, newState, newContext, "0")
		}
	case ab.ConsensusType_MIG_STATE_COMMIT:
		if newType != "etcdraft" {
			return errors.Errorf(unExpType, newState, newType, "etcdraft")
		}
		if newContext <= 0 {
			return errors.Errorf(unExpCtx, newState, newContext, ">0")
		}
	case ab.ConsensusType_MIG_STATE_ABORT:
		if newType != "kafka" {
			return errors.Errorf(unExpType, newState, newType, "kafka")
		}
		if newContext <= 0 {
			return errors.Errorf(unExpCtx, newState, newContext, ">0")
		}

	default:
		return errors.Errorf("Consensus-type migration, state=%s, not permitted on system channel", newState)
	}

	// The following code explicitly checks for permitted transitions; all other transitions return an error.
	if oldType != newType {

		if oldType == "kafka" && newType == "etcdraft" {
			// On the system channels, this is permitted, green path commit
			isSysCommit := (oldState == ab.ConsensusType_MIG_STATE_START) && (newState == ab.ConsensusType_MIG_STATE_COMMIT)
			if !isSysCommit {
				return errors.Errorf("Attempted to change consensus type from %s to %s, unexpected state transition: %s to %s",
					oldType, newType, oldState, newState)
			}
		} else if oldType == "etcdraft" && newType == "kafka" {
			return errors.Errorf("Attempted to change consensus type from %s to %s, not permitted on system channel", oldType, newType)
		} else {
			return errors.Errorf("Attempted to change consensus type from %s to %s, not supported", oldType, newType)
		}

		logger.Debugf("Consensus-type migration, from %s to %s, state transition: %s to %s", oldType, newType, oldState, newState)
	} else {
		// This is always permitted, not a migration
		isNotMig := (oldState == ab.ConsensusType_MIG_STATE_NONE) && (newState == oldState)
		if isNotMig {
			logger.Debugf("Not Consensus-type migration, type %s, old-state = new-state = %s", oldType, oldState)
			return nil
		}

		// Migration state may change when the type stays the same
		if oldType == "kafka" {
			// In the "green" path: the system channel starts migration
			isStart := (oldState == ab.ConsensusType_MIG_STATE_NONE) && (newState == ab.ConsensusType_MIG_STATE_START)
			// In the "abort" path: the system channel aborts a migration
			isAbort := (oldState == ab.ConsensusType_MIG_STATE_START) && (newState == ab.ConsensusType_MIG_STATE_ABORT)
			// In the "abort" path: the system channel reconfigures after an abort, not a migration
			isNotMigAfterAbort := (oldState == ab.ConsensusType_MIG_STATE_ABORT) && (newState == ab.ConsensusType_MIG_STATE_NONE)
			// In the "abort" path: the system channel starts a new migration attempt after an abort
			isStartAfterAbort := (oldState == ab.ConsensusType_MIG_STATE_ABORT) && (newState == ab.ConsensusType_MIG_STATE_START)
			if !(isNotMig || isStart || isAbort || isNotMigAfterAbort || isStartAfterAbort) {
				return errors.Errorf("Consensus type %s, unexpected migration state transition: %s to %s",
					oldType, oldState, newState)
			}
		} else if oldType == "etcdraft" {
			// In the "green" path: the system channel reconfigures after a successful migration
			isConfAfterSuccess := (oldState == ab.ConsensusType_MIG_STATE_COMMIT) && (newState == ab.ConsensusType_MIG_STATE_NONE)
			if !(isNotMig || isConfAfterSuccess) {
				return errors.Errorf("Consensus type %s, unexpected migration state transition: %s to %s",
					oldType, oldState.String(), newState)
			}
		}

		logger.Debugf("Consensus-type migration, type %s, state transition: %s to %s", oldType, oldState, newState)
	}

	return nil
}
370522
func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}

	// check valid feature names are provided
	for k := range featureGates {
		if !features.Supports(features.InitFeatureGates, k) {
			allErrs = append(allErrs, field.Invalid(fldPath, featureGates,
				fmt.Sprintf("%s is not a valid feature name.", k)))
		}
	}

	return allErrs
}
1121092
func (m *postgresMigrator) step(fn MigrationFunc) error {
	if fn == nil {
		panic("step called but no function!")
	}
	tx, err := m.db.Begin()
	if err != nil {
		return err
	}
	if err := fn(tx); err != nil {
		fmt.Printf("got an error trying to run a step: %v", err)
		if err := tx.Rollback(); err != nil {
			panic(fmt.Sprintf("unable to rollback migration transaction:%v", err))
		}
		return err
	}
	if err := tx.Commit(); err != nil {
		panic(fmt.Sprintf("unable to commit migration transaction:%v", err))
	}
	return nil
}
192024
func MergeStepWith(step, otherStep stepmanModels.StepModel) (stepmanModels.StepModel, error) {
	if otherStep.Title != nil {
		step.Title = pointers.NewStringPtr(*otherStep.Title)
	}
	if otherStep.Summary != nil {
		step.Summary = pointers.NewStringPtr(*otherStep.Summary)
	}
	if otherStep.Description != nil {
		step.Description = pointers.NewStringPtr(*otherStep.Description)
	}

	if otherStep.Website != nil {
		step.Website = pointers.NewStringPtr(*otherStep.Website)
	}
	if otherStep.SourceCodeURL != nil {
		step.SourceCodeURL = pointers.NewStringPtr(*otherStep.SourceCodeURL)
	}
	if otherStep.SupportURL != nil {
		step.SupportURL = pointers.NewStringPtr(*otherStep.SupportURL)
	}

	if otherStep.PublishedAt != nil {
		step.PublishedAt = pointers.NewTimePtr(*otherStep.PublishedAt)
	}
	if otherStep.Source != nil {
		step.Source = new(stepmanModels.StepSourceModel)

		if otherStep.Source.Git != "" {
			step.Source.Git = otherStep.Source.Git
		}
		if otherStep.Source.Commit != "" {
			step.Source.Commit = otherStep.Source.Commit
		}
	}
	if len(otherStep.AssetURLs) > 0 {
		step.AssetURLs = otherStep.AssetURLs
	}

	if len(otherStep.HostOsTags) > 0 {
		step.HostOsTags = otherStep.HostOsTags
	}
	if len(otherStep.ProjectTypeTags) > 0 {
		step.ProjectTypeTags = otherStep.ProjectTypeTags
	}
	if len(otherStep.TypeTags) > 0 {
		step.TypeTags = otherStep.TypeTags
	}
	if len(otherStep.Dependencies) > 0 {
		step.Dependencies = otherStep.Dependencies
	}
	if otherStep.Toolkit != nil {
		step.Toolkit = new(stepmanModels.StepToolkitModel)
		*step.Toolkit = *otherStep.Toolkit
	}
	if otherStep.Deps != nil && (len(otherStep.Deps.Brew) > 0 || len(otherStep.Deps.AptGet) > 0 || len(otherStep.Deps.CheckOnly) > 0) {
		step.Deps = otherStep.Deps
	}
	if otherStep.IsRequiresAdminUser != nil {
		step.IsRequiresAdminUser = pointers.NewBoolPtr(*otherStep.IsRequiresAdminUser)
	}

	if otherStep.IsAlwaysRun != nil {
		step.IsAlwaysRun = pointers.NewBoolPtr(*otherStep.IsAlwaysRun)
	}
	if otherStep.IsSkippable != nil {
		step.IsSkippable = pointers.NewBoolPtr(*otherStep.IsSkippable)
	}
	if otherStep.RunIf != nil {
		step.RunIf = pointers.NewStringPtr(*otherStep.RunIf)
	}
	if otherStep.Timeout != nil {
		step.Timeout = pointers.NewIntPtr(*otherStep.Timeout)
	}

	for _, input := range step.Inputs {
		key, _, err := input.GetKeyValuePair()
		if err != nil {
			return stepmanModels.StepModel{}, err
		}
		otherInput, found := getInputByKey(otherStep, key)
		if found {
			err := MergeEnvironmentWith(&input, otherInput)
			if err != nil {
				return stepmanModels.StepModel{}, err
			}
		}
	}

	for _, output := range step.Outputs {
		key, _, err := output.GetKeyValuePair()
		if err != nil {
			return stepmanModels.StepModel{}, err
		}
		otherOutput, found := getOutputByKey(otherStep, key)
		if found {
			err := MergeEnvironmentWith(&output, otherOutput)
			if err != nil {
				return stepmanModels.StepModel{}, err
			}
		}
	}

	return step, nil
}
1221965
func (m *Migrator) CreateMigrationsTable() error {
	_, err := m.DB.Exec(m.dbAdapter.CreateMigrationTableSql())
	if err != nil {
		m.logger.Fatalf("Error creating migrations table: %v", err)
	}

	m.logger.Printf("Created migrations table: %s", migrationTableName)

	return nil
}
1290140
func (st *State) CreateMigration(spec MigrationSpec) (ModelMigration, error) {
	if st.IsController() {
		return nil, errors.New("controllers can't be migrated")
	}
	if err := spec.Validate(); err != nil {
		return nil, errors.Trace(err)
	}
	if err := checkTargetController(st, spec.TargetInfo.ControllerTag); err != nil {
		return nil, errors.Trace(err)
	}

	now := st.clock().Now().UnixNano()
	modelUUID := st.ModelUUID()
	var doc modelMigDoc
	var statusDoc modelMigStatusDoc

	msg := "starting"
	ops, err := migStatusHistoryAndOps(st, migration.QUIESCE, now, msg)
	if err != nil {
		return nil, errors.Trace(err)
	}

	buildTxn := func(int) ([]txn.Op, error) {
		model, err := st.Model()
		if err != nil {
			return nil, errors.Annotate(err, "failed to load model")
		}
		if model.Life() != Alive {
			return nil, errors.New("model is not alive")
		}

		if isActive, err := st.IsMigrationActive(); err != nil {
			return nil, errors.Trace(err)
		} else if isActive {
			return nil, errors.New("already in progress")
		}

		macsJSON, err := macaroonsToJSON(spec.TargetInfo.Macaroons)
		if err != nil {
			return nil, errors.Trace(err)
		}

		attempt, err := sequence(st, "modelmigration")
		if err != nil {
			return nil, errors.Trace(err)
		}

		userDocs, err := modelUserDocs(model)
		if err != nil {
			return nil, errors.Trace(err)
		}

		id := fmt.Sprintf("%s:%d", modelUUID, attempt)
		doc = modelMigDoc{
			Id:                    id,
			ModelUUID:             modelUUID,
			Attempt:               attempt,
			InitiatedBy:           spec.InitiatedBy.Id(),
			TargetController:      spec.TargetInfo.ControllerTag.Id(),
			TargetControllerAlias: spec.TargetInfo.ControllerAlias,
			TargetAddrs:           spec.TargetInfo.Addrs,
			TargetCACert:          spec.TargetInfo.CACert,
			TargetAuthTag:         spec.TargetInfo.AuthTag.String(),
			TargetPassword:        spec.TargetInfo.Password,
			TargetMacaroons:       macsJSON,
			ModelUsers:            userDocs,
		}

		statusDoc = modelMigStatusDoc{
			Id:               id,
			StartTime:        now,
			Phase:            migration.QUIESCE.String(),
			PhaseChangedTime: now,
			StatusMessage:    msg,
		}

		ops := append(ops, []txn.Op{{
			C:      migrationsC,
			Id:     doc.Id,
			Assert: txn.DocMissing,
			Insert: &doc,
		}, {
			C:      migrationsStatusC,
			Id:     statusDoc.Id,
			Assert: txn.DocMissing,
			Insert: &statusDoc,
		}, {
			C:      migrationsActiveC,
			Id:     modelUUID,
			Assert: txn.DocMissing,
			Insert: bson.M{"id": doc.Id},
		}, {
			C:      modelsC,
			Id:     modelUUID,
			Assert: txn.DocExists,
			Update: bson.M{"$set": bson.M{
				"migration-mode": MigrationModeExporting,
			}},
		}, model.assertActiveOp(),
		}...)
		return ops, nil
	}
	if err := st.db().Run(buildTxn); err != nil {
		return nil, errors.Annotate(err, "failed to create migration")
	}

	return &modelMigration{
		doc:       doc,
		statusDoc: statusDoc,
		st:        st,
	}, nil
}
54775
func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error {
	log.Printf("[TRACE] backendMigrateState: migrating %q workspace to %q workspace", opts.oneEnv, opts.twoEnv)

	stateOne, err := opts.One.StateMgr(opts.oneEnv)
	if err != nil {
		return fmt.Errorf(strings.TrimSpace(
			errMigrateSingleLoadDefault), opts.OneType, err)
	}
	if err := stateOne.RefreshState(); err != nil {
		return fmt.Errorf(strings.TrimSpace(
			errMigrateSingleLoadDefault), opts.OneType, err)
	}

	// Do not migrate workspaces without state.
	if stateOne.State().Empty() {
		log.Print("[TRACE] backendMigrateState: source workspace has empty state, so nothing to migrate")
		return nil
	}

	stateTwo, err := opts.Two.StateMgr(opts.twoEnv)
	if err == backend.ErrDefaultWorkspaceNotSupported {
		// If the backend doesn't support using the default state, we ask the user
		// for a new name and migrate the default state to the given named state.
		stateTwo, err = func() (statemgr.Full, error) {
			log.Print("[TRACE] backendMigrateState: target doesn't support a default workspace, so we must prompt for a new name")
			name, err := m.UIInput().Input(context.Background(), &terraform.InputOpts{
				Id: "new-state-name",
				Query: fmt.Sprintf(
					"[reset][bold][yellow]The %q backend configuration only allows "+
						"named workspaces![reset]",
					opts.TwoType),
				Description: strings.TrimSpace(inputBackendNewWorkspaceName),
			})
			if err != nil {
				return nil, fmt.Errorf("Error asking for new state name: %s", err)
			}

			// Update the name of the target state.
			opts.twoEnv = name

			stateTwo, err := opts.Two.StateMgr(opts.twoEnv)
			if err != nil {
				return nil, err
			}

			// If the currently selected workspace is the default workspace, then set
			// the named workspace as the new selected workspace.
			if m.Workspace() == backend.DefaultStateName {
				if err := m.SetWorkspace(opts.twoEnv); err != nil {
					return nil, fmt.Errorf("Failed to set new workspace: %s", err)
				}
			}

			return stateTwo, nil
		}()
	}
	if err != nil {
		return fmt.Errorf(strings.TrimSpace(
			errMigrateSingleLoadDefault), opts.TwoType, err)
	}
	if err := stateTwo.RefreshState(); err != nil {
		return fmt.Errorf(strings.TrimSpace(
			errMigrateSingleLoadDefault), opts.TwoType, err)
	}

	// Check if we need migration at all.
	// This is before taking a lock, because they may also correspond to the same lock.
	one := stateOne.State()
	two := stateTwo.State()

	// no reason to migrate if the state is already there
	if one.Equal(two) {
		// Equal isn't identical; it doesn't check lineage.
		sm1, _ := stateOne.(statemgr.PersistentMeta)
		sm2, _ := stateTwo.(statemgr.PersistentMeta)
		if one != nil && two != nil {
			if sm1 == nil || sm2 == nil {
				log.Print("[TRACE] backendMigrateState: both source and destination workspaces have no state, so no migration is needed")
				return nil
			}
			if sm1.StateSnapshotMeta().Lineage == sm2.StateSnapshotMeta().Lineage {
				log.Printf("[TRACE] backendMigrateState: both source and destination workspaces have equal state with lineage %q, so no migration is needed", sm1.StateSnapshotMeta().Lineage)
				return nil
			}
		}
	}

	if m.stateLock {
		lockCtx := context.Background()

		lockerOne := clistate.NewLocker(lockCtx, m.stateLockTimeout, m.Ui, m.Colorize())
		if err := lockerOne.Lock(stateOne, "migration source state"); err != nil {
			return fmt.Errorf("Error locking source state: %s", err)
		}
		defer lockerOne.Unlock(nil)

		lockerTwo := clistate.NewLocker(lockCtx, m.stateLockTimeout, m.Ui, m.Colorize())
		if err := lockerTwo.Lock(stateTwo, "migration destination state"); err != nil {
			return fmt.Errorf("Error locking destination state: %s", err)
		}
		defer lockerTwo.Unlock(nil)

		// We now own a lock, so double check that we have the version
		// corresponding to the lock.
		log.Print("[TRACE] backendMigrateState: refreshing source workspace state")
		if err := stateOne.RefreshState(); err != nil {
			return fmt.Errorf(strings.TrimSpace(
				errMigrateSingleLoadDefault), opts.OneType, err)
		}
		log.Print("[TRACE] backendMigrateState: refreshing target workspace state")
		if err := stateTwo.RefreshState(); err != nil {
			return fmt.Errorf(strings.TrimSpace(
				errMigrateSingleLoadDefault), opts.OneType, err)
		}

		one = stateOne.State()
		two = stateTwo.State()
	}

	var confirmFunc func(state.State, state.State, *backendMigrateOpts) (bool, error)
	switch {
	// No migration necessary
	case one.Empty() && two.Empty():
		log.Print("[TRACE] backendMigrateState: both source and destination workspaces have empty state, so no migration is required")
		return nil

	// No migration necessary if we're inheriting state.
	case one.Empty() && !two.Empty():
		log.Print("[TRACE] backendMigrateState: source workspace has empty state, so no migration is required")
		return nil

	// We have existing state moving into no state. Ask the user if
	// they'd like to do this.
	case !one.Empty() && two.Empty():
		log.Print("[TRACE] backendMigrateState: target workspace has empty state, so might copy source workspace state")
		confirmFunc = m.backendMigrateEmptyConfirm

	// Both states are non-empty, meaning we need to determine which
	// state should be used and update accordingly.
	case !one.Empty() && !two.Empty():
		log.Print("[TRACE] backendMigrateState: both source and destination workspaces have states, so might overwrite destination with source")
		confirmFunc = m.backendMigrateNonEmptyConfirm
	}

	if confirmFunc == nil {
		panic("confirmFunc must not be nil")
	}

	if !opts.force {
		// Abort if we can't ask for input.
		if !m.input {
			log.Print("[TRACE] backendMigrateState: can't prompt for input, so aborting migration")
			return errors.New("error asking for state migration action: input disabled")
		}

		// Confirm with the user whether we want to copy state over
		confirm, err := confirmFunc(stateOne, stateTwo, opts)
		if err != nil {
			log.Print("[TRACE] backendMigrateState: error reading input, so aborting migration")
			return err
		}
		if !confirm {
			log.Print("[TRACE] backendMigrateState: user cancelled at confirmation prompt, so aborting migration")
			return nil
		}
	}

	// Confirmed! We'll have the statemgr package handle the migration, which
	// includes preserving any lineage/serial information where possible, if
	// both managers support such metadata.
	log.Print("[TRACE] backendMigrateState: migration confirmed, so migrating")
	if err := statemgr.Migrate(stateTwo, stateOne); err != nil {
		return fmt.Errorf(strings.TrimSpace(errBackendStateCopy),
			opts.OneType, opts.TwoType, err)
	}
	if err := stateTwo.PersistState(); err != nil {
		return fmt.Errorf(strings.TrimSpace(errBackendStateCopy),
			opts.OneType, opts.TwoType, err)
	}

	// And we're done.
	return nil
}
141327
func stateStepsFor21() []Step {
	return []Step{
		&upgradeStep{
			description: "add attempt to migration docs",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().AddMigrationAttempt()
			},
		},
		&upgradeStep{
			description: "add sequences to track used local charm revisions",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().AddLocalCharmSequences()
			},
		},
		&upgradeStep{
			description: "update lxd cloud/credentials",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return updateLXDCloudCredentials(context.State())
			},
		},
	}
}
158898
func (f *Facade) MigrateServices(ctx datastore.Context, req dao.ServiceMigrationRequest) error {
	defer ctx.Metrics().Stop(ctx.Metrics().Start("Facade.MigrateServices"))
	logger := plog.WithFields(log.Fields{
		"tenantid":  req.ServiceID,
	})
	logger.Debug("Started Facade.MigrateServices")
	defer logger.Debug("Finished Facade.MigrateServices")

	var svcAll []service.Service
	// validate service updates
	for _, svc := range req.Modified {
		if _, err := f.validateServiceUpdate(ctx, svc); err != nil {
			logger.WithError(err).WithFields(log.Fields{
				"servicename": svc.Name,
				"serviceid": svc.ID,
			}).Error("Could not validate service for update")
			return err
		}
		svcAll = append(svcAll, *svc)
	}
	// validate service adds
	for _, svc := range req.Added {
		if err := f.validateServiceAdd(ctx, svc); err != nil {
			logger.WithError(err).WithFields(log.Fields{
				"servicename": svc.Name,
				"serviceid": svc.ID,
			}).Error("Could not validate service for add")
			return err
		} else if svc.ID, err = utils.NewUUID36(); err != nil {
			logger.WithError(err).WithFields(log.Fields{
				"servicename": svc.Name,
			}).Error("Could not generate id for new service")
			return err
		}
		svcAll = append(svcAll, *svc)
	}
	// validate service deployments
	for _, sdreq := range req.Deploy {
		svcs, err := f.validateServiceDeployment(ctx, sdreq.ParentID, &sdreq.Service)
		if err != nil {
			logger.WithError(err).WithFields(log.Fields{
				"servicename":  sdreq.Service.Name,
			}).Error("Could not validate service for deployment")
			return err
		}
		svcAll = append(svcAll, svcs...)
	}
	// validate service migration
	if err := f.validateServiceMigration(ctx, svcAll, req.ServiceID); err != nil {
		logger.WithError(err).Error("Could not validate migration of services")
		return err
	}
	logger.Info("Validation checks passed for service migration")

	// Do migration
	for _, filter := range req.LogFilters {
		var action string
		existingFilter, err := f.logFilterStore.Get(ctx, filter.Name, filter.Version)
		if err == nil {
			existingFilter.Filter = filter.Filter
			err = f.logFilterStore.Put(ctx, existingFilter)
			action = "update"
		} else if err != nil && datastore.IsErrNoSuchEntity(err) {
			err = f.logFilterStore.Put(ctx, &filter)
			action = "add"
		}
		if err != nil {
			logger.WithError(err).WithFields(log.Fields{
				"action": action,
				"filtername": filter.Name,
			}).Error("Failed to save log filter")
			return err
		}
		logger.WithFields(log.Fields{
			"action": action,
			"filtername": filter.Name,
			"filterversion": filter.Version,
		}).Debug("Service migration saved LogFilter")
	}
	for _, svc := range req.Modified {
		if err := f.MigrateService(ctx, *svc); err != nil {
			return err
		}
	}
	for _, svc := range req.Added {
		if err := f.AddService(ctx, *svc); err != nil {
			return err
		}
	}
	for _, sdreq := range req.Deploy {
		if _, err := f.DeployService(ctx, "", sdreq.ParentID, false, sdreq.Service); err != nil {
			logger.WithError(err).WithFields(log.Fields{
				"servicename":  sdreq.Service.Name,
			}).Error("Could not deploy service definition")
			return err
		}
	}
	logger.Info("Service migration completed successfully")

	// CC-3514 - rebuild logstash config in case the set of auditable log files has changed
	f.ReloadLogstashConfig(ctx)
	return nil
}
605012
func stateStepsFor20() []Step {
	return []Step{
		&upgradeStep{
			description: "strip @local from local user names",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().StripLocalUserDomain()
			},
		},
		&upgradeStep{
			description: "rename addmodel permission to add-model",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().RenameAddModelPermission()
			},
		},
	}
}
639693
func (m *Migrator) getMigrationStatuses() error {
	for _, migration := range m.migrations {
		row := m.DB.QueryRow(m.dbAdapter.GetMigrationSql(), migration.Id)
		var mid uint64
		err := row.Scan(&mid)
		if err == sql.ErrNoRows {
			continue
		}
		if err != nil {
			m.logger.Printf(
				"Error getting migration status for %s: %v",
				migration.Name,
				err,
			)
			return err
		}
		migration.Status = Active
	}
	return nil
}
488322
func (v *TransitionType) Validate() error {

	if v.StorageClass == nil {
		return errors.ParameterRequiredError{
			ParameterName: "StorageClass",
			ParentName:    "Transition",
		}
	}

	return nil
}
183448
func (m *MockLegacyDeploymentStateMigrator) MigrateIfExists(arg0 string) (bool, error) {
	ret := m.ctrl.Call(m, "MigrateIfExists", arg0)
	ret0, _ := ret[0].(bool)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}
751635
func (api *API) MigrationStatus() (params.MasterMigrationStatus, error) {
	empty := params.MasterMigrationStatus{}

	mig, err := api.backend.LatestMigration()
	if err != nil {
		return empty, errors.Annotate(err, "retrieving model migration")
	}
	target, err := mig.TargetInfo()
	if err != nil {
		return empty, errors.Annotate(err, "retrieving target info")
	}
	phase, err := mig.Phase()
	if err != nil {
		return empty, errors.Annotate(err, "retrieving phase")
	}
	macsJSON, err := json.Marshal(target.Macaroons)
	if err != nil {
		return empty, errors.Annotate(err, "marshalling macaroons")
	}
	return params.MasterMigrationStatus{
		Spec: params.MigrationSpec{
			ModelTag: names.NewModelTag(mig.ModelUUID()).String(),
			TargetInfo: params.MigrationTargetInfo{
				ControllerTag: target.ControllerTag.String(),
				Addrs:         target.Addrs,
				CACert:        target.CACert,
				AuthTag:       target.AuthTag.String(),
				Password:      target.Password,
				Macaroons:     string(macsJSON),
			},
		},
		MigrationId:      mig.Id(),
		Phase:            phase.String(),
		PhaseChangedTime: mig.PhaseChangedTime(),
	}, nil
}
1348186
func validatePathNoBacksteps(targetPath string, fldPath *field.Path) field.ErrorList {
	allErrs := field.ErrorList{}
	parts := strings.Split(filepath.ToSlash(targetPath), "/")
	for _, item := range parts {
		if item == ".." {
			allErrs = append(allErrs, field.Invalid(fldPath, targetPath, "must not contain '..'"))
			break // even for `../../..`, one error is sufficient to make the point
		}
	}
	return allErrs
}
877388
func stateStepsFor26() []Step {
	return []Step{
		&upgradeStep{
			description: "update k8s storage config",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().UpdateKubernetesStorageConfig()
			},
		},
		&upgradeStep{
			description: "remove instanceCharmProfileData collection",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().RemoveInstanceCharmProfileDataCollection()
			},
		},
	}
}
683585
func stateStepsFor254() []Step {
	return []Step{
		&upgradeStep{
			description: "ensure default modification status is set for machines",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().EnsureDefaultModificationStatus()
			},
		},
		&upgradeStep{
			description: "ensure device constraints exists for applications",
			targets:     []Target{DatabaseMaster},
			run: func(context Context) error {
				return context.State().EnsureApplicationDeviceConstraints()
			},
		},
	}
}