Exemple #1
0
// Phase implements ModelMigration.
func (mig *modelMigration) Phase() (migration.Phase, error) {
	phase, ok := migration.ParsePhase(mig.statusDoc.Phase)
	if !ok {
		return phase, errors.Errorf("invalid phase in DB: %v", mig.statusDoc.Phase)
	}
	return phase, nil
}
Exemple #2
0
// MinionReports returns details of the reports made by migration
// minions to the controller for the current migration phase.
func (c *Client) MinionReports() (migration.MinionReports, error) {
	var in params.MinionReports
	var out migration.MinionReports

	err := c.caller.FacadeCall("MinionReports", nil, &in)
	if err != nil {
		return out, errors.Trace(err)
	}

	out.MigrationId = in.MigrationId

	phase, ok := migration.ParsePhase(in.Phase)
	if !ok {
		return out, errors.Errorf("invalid phase: %q", in.Phase)
	}
	out.Phase = phase

	out.SuccessCount = in.SuccessCount
	out.UnknownCount = in.UnknownCount

	out.SomeUnknownMachines, out.SomeUnknownUnits, err = groupTagIds(in.UnknownSample)
	if err != nil {
		return out, errors.Annotate(err, "processing unknown agents")
	}

	out.FailedMachines, out.FailedUnits, err = groupTagIds(in.Failed)
	if err != nil {
		return out, errors.Annotate(err, "processing failed agents")
	}

	return out, nil
}
Exemple #3
0
// MigrationStatus returns the details and progress of the latest
// model migration.
func (c *Client) MigrationStatus() (migration.MigrationStatus, error) {
	var empty migration.MigrationStatus
	var status params.MasterMigrationStatus
	err := c.caller.FacadeCall("MigrationStatus", nil, &status)
	if err != nil {
		return empty, errors.Trace(err)
	}

	modelTag, err := names.ParseModelTag(status.Spec.ModelTag)
	if err != nil {
		return empty, errors.Annotatef(err, "parsing model tag")
	}

	phase, ok := migration.ParsePhase(status.Phase)
	if !ok {
		return empty, errors.New("unable to parse phase")
	}

	target := status.Spec.TargetInfo
	controllerTag, err := names.ParseControllerTag(target.ControllerTag)
	if err != nil {
		return empty, errors.Annotatef(err, "parsing controller tag")
	}

	authTag, err := names.ParseUserTag(target.AuthTag)
	if err != nil {
		return empty, errors.Annotatef(err, "unable to parse auth tag")
	}

	var macs []macaroon.Slice
	if target.Macaroons != "" {
		if err := json.Unmarshal([]byte(target.Macaroons), &macs); err != nil {
			return empty, errors.Annotatef(err, "unmarshalling macaroon")
		}
	}

	return migration.MigrationStatus{
		MigrationId:      status.MigrationId,
		ModelUUID:        modelTag.Id(),
		ExternalControl:  status.Spec.ExternalControl,
		Phase:            phase,
		PhaseChangedTime: status.PhaseChangedTime,
		TargetInfo: migration.TargetInfo{
			ControllerTag: controllerTag,
			Addrs:         target.Addrs,
			CACert:        target.CACert,
			AuthTag:       authTag,
			Password:      target.Password,
			Macaroons:     macs,
		},
	}, nil
}
Exemple #4
0
// SetPhase sets the phase of the active model migration. The provided
// phase must be a valid phase value, for example QUIESCE" or
// "ABORT". See the core/migration package for the complete list.
func (api *API) SetPhase(args params.SetMigrationPhaseArgs) error {
	mig, err := api.backend.GetModelMigration()
	if err != nil {
		return errors.Annotate(err, "could not get migration")
	}

	phase, ok := coremigration.ParsePhase(args.Phase)
	if !ok {
		return errors.Errorf("invalid phase: %q", args.Phase)
	}

	err = mig.SetPhase(phase)
	return errors.Annotate(err, "failed to set phase")
}
Exemple #5
0
// Report allows a migration minion to submit whether it succeeded or
// failed for a specific migration phase.
func (api *API) Report(info params.MinionReport) error {
	phase, ok := migration.ParsePhase(info.Phase)
	if !ok {
		return errors.New("unable to parse phase")
	}

	mig, err := api.backend.Migration(info.MigrationId)
	if err != nil {
		return errors.Trace(err)
	}

	err = mig.SubmitMinionReport(api.authorizer.GetAuthTag(), phase, info.Success)
	return errors.Trace(err)
}
Exemple #6
0
func (w *migrationStatusWatcher) loop() error {
	w.newResult = func() interface{} { return new(params.MigrationStatus) }
	w.call = makeWatcherAPICaller(w.caller, "MigrationStatusWatcher", w.id)
	w.commonWatcher.init()
	go w.commonLoop()

	for {
		var data interface{}
		var ok bool

		select {
		case data, ok = <-w.in:
			if !ok {
				// The tomb is already killed with the correct error
				// at this point, so just return.
				return nil
			}
		case <-w.tomb.Dying():
			return nil
		}

		inStatus := *data.(*params.MigrationStatus)
		phase, ok := migration.ParsePhase(inStatus.Phase)
		if !ok {
			return errors.Errorf("invalid phase %q", inStatus.Phase)
		}
		outStatus := watcher.MigrationStatus{
			MigrationId:    inStatus.MigrationId,
			Attempt:        inStatus.Attempt,
			Phase:          phase,
			SourceAPIAddrs: inStatus.SourceAPIAddrs,
			SourceCACert:   inStatus.SourceCACert,
			TargetAPIAddrs: inStatus.TargetAPIAddrs,
			TargetCACert:   inStatus.TargetCACert,
		}
		select {
		case w.out <- outStatus:
		case <-w.tomb.Dying():
			return nil
		}
	}
}
Exemple #7
0
// GetMigrationStatus implements Client.
func (c *client) GetMigrationStatus() (MigrationStatus, error) {
	var empty MigrationStatus
	var status params.FullMigrationStatus
	err := c.caller.FacadeCall("GetMigrationStatus", nil, &status)
	if err != nil {
		return empty, errors.Trace(err)
	}

	modelTag, err := names.ParseModelTag(status.Spec.ModelTag)
	if err != nil {
		return empty, errors.Annotatef(err, "parsing model tag")
	}

	phase, ok := migration.ParsePhase(status.Phase)
	if !ok {
		return empty, errors.New("unable to parse phase")
	}

	target := status.Spec.TargetInfo
	controllerTag, err := names.ParseModelTag(target.ControllerTag)
	if err != nil {
		return empty, errors.Annotatef(err, "parsing controller tag")
	}

	authTag, err := names.ParseUserTag(target.AuthTag)
	if err != nil {
		return empty, errors.Annotatef(err, "unable to parse auth tag")
	}

	return MigrationStatus{
		ModelUUID: modelTag.Id(),
		Attempt:   status.Attempt,
		Phase:     phase,
		TargetInfo: migration.TargetInfo{
			ControllerTag: controllerTag,
			Addrs:         target.Addrs,
			CACert:        target.CACert,
			AuthTag:       authTag,
			Password:      target.Password,
		},
	}, nil
}
Exemple #8
0
// Phase returns the current migration.Phase for the supplied model UUID.
func (facade *Facade) Phase(uuid string) (migration.Phase, error) {
	results := params.PhaseResults{}
	err := facade.call("Phase", uuid, &results)
	if err != nil {
		return migration.UNKNOWN, errors.Trace(err)
	}
	if count := len(results.Results); count != 1 {
		return migration.UNKNOWN, countError(count)
	}
	result := results.Results[0]
	if result.Error != nil {
		return migration.UNKNOWN, errors.Trace(result.Error)
	}
	phase, ok := migration.ParsePhase(result.Phase)
	if !ok {
		err := errors.Errorf("unknown phase %q", result.Phase)
		return migration.UNKNOWN, err
	}
	return phase, nil
}
Exemple #9
0
func (s *PhaseSuite) TestParseInvalid(c *gc.C) {
	phase, ok := migration.ParsePhase("foo")
	c.Check(phase, gc.Equals, migration.UNKNOWN)
	c.Check(ok, jc.IsFalse)
}
Exemple #10
0
func (s *PhaseSuite) TestParseValid(c *gc.C) {
	phase, ok := migration.ParsePhase("REAP")
	c.Check(phase, gc.Equals, migration.REAP)
	c.Check(ok, jc.IsTrue)
}