Esempio n. 1
0
func (f *FleetTunnel) Destroy(events chan Event, unitNames ...string) error {
	log.Debugf("destroying %v", unitNames)

	var ae aerr.AggregateError

	for _, unit := range unitNames {
		events <- newEvent(unit, "destroying")
		if notFound, err := f.destroyUnitWithRetry(unit); notFound {
			continue
		} else if err != nil {
			ae.Add(maskAny(fmt.Errorf("Error destroying units: %v", err)))
			continue
		}

		if f.NoBlock {
			attempts := f.BlockAttempts
			retry := func() bool {
				if f.BlockAttempts < 1 {
					return true
				}
				attempts--
				if attempts == 0 {
					return false
				}
				return true
			}

			for retry() {
				exists, err := f.unitExists(unit)
				if err != nil {
					ae.Add(maskAny(fmt.Errorf("Error destroying units: %v", err)))
					break
				}

				if !exists {
					break
				}
				time.Sleep(defaultSleepTime)
			}
		}

		events <- newEvent(unit, "destroyed")
	}

	if !ae.IsEmpty() {
		return maskAny(&ae)
	}

	return nil
}
Esempio n. 2
0
// lazyCreateUnits iterates over a set of unit names and, for each, attempts to
// ensure that a unit by that name exists in the Registry, by checking a number
// of conditions and acting on the first one that succeeds, in order of:
//  1. a unit by that name already existing in the Registry
//  2. a unit file by that name existing on disk
//  3. a corresponding unit template (if applicable) existing in the Registry
//  4. a corresponding unit template (if applicable) existing on disk
// Any error encountered during these steps is returned immediately (i.e.
// subsequent Jobs are not acted on). An error is also returned if none of the
// above conditions match a given Job.
func (f *FleetTunnel) lazyCreateUnits(units UnitDataList, events chan Event) error {
	errchan := make(chan error)
	blockAttempts := f.BlockAttempts
	var wg sync.WaitGroup
	for i := 0; i < units.Len(); i++ {
		u := units.Get(i)
		name := u.Name()
		create, err := f.checkUnitCreation(name)
		if err != nil {
			return err
		} else if !create {
			continue
		}

		// Assume that the name references a local unit file on
		// disk or if it is an instance unit and if so get its
		// corresponding unit
		uf, err := unit.NewUnitFile(u.Content())
		if err != nil {
			return err
		}

		events <- newEvent(name, "creating unit")
		_, err = f.createUnit(name, uf)
		if err != nil {
			return err
		}

		wg.Add(1)
		go f.checkUnitState(name, job.JobStateInactive, blockAttempts, events, &wg, errchan)
	}

	go func() {
		wg.Wait()
		close(errchan)
	}()

	var ae aerr.AggregateError
	for msg := range errchan {
		ae.Add(maskAny(fmt.Errorf("Error waiting on unit creation: %v\n", msg)))
	}

	if !ae.IsEmpty() {
		return maskAny(&ae)
	}

	return nil
}
Esempio n. 3
0
File: fleet.go Progetto: pulcy/j2
// tryWaitForUnitStates tries to wait for units to reach the desired state.
// It takes 5 arguments, the units to wait for, the desired state, the
// desired JobState, how many attempts before timing out and a writer
// interface.
// tryWaitForUnitStates polls each of the indicated units until they
// reach the desired state. If maxAttempts is negative, then it will not
// wait, it will assume that all units reached their desired state.
// If maxAttempts is zero tryWaitForUnitStates will retry forever, and
// if it is greater than zero, it will retry up to the indicated value.
// It returns 0 on success or 1 on errors.
func (f *FleetTunnel) tryWaitForUnitStates(units []string, state string, js job.JobState, maxAttempts int, events chan Event) error {
	// We do not wait just assume we reached the desired state
	if maxAttempts <= -1 {
		for _, name := range units {
			events <- newEvent(name, fmt.Sprintf("triggered %s", name))
		}
		return nil
	}

	errchan := f.waitForUnitStates(units, js, maxAttempts, events)
	var ae aerr.AggregateError
	for err := range errchan {
		ae.Add(maskAny(err))
	}

	if !ae.IsEmpty() {
		return maskAny(&ae)
	}

	return nil
}