// TestMetaContinuous specifically checks that you cannot enable the // "continuous" flag on non-continuous work specs. func (s *Suite) TestMetaContinuous(c *check.C) { var ( err error spec coordinate.WorkSpec meta coordinate.WorkSpecMeta ) // ...also... spec, err = s.Namespace.SetWorkSpec(map[string]interface{}{ "name": "spec", "min_gb": 1, }) c.Assert(err, check.IsNil) meta, err = spec.Meta(false) c.Assert(err, check.IsNil) c.Check(meta.Continuous, check.Equals, false) c.Check(meta.CanBeContinuous, check.Equals, false) meta.Continuous = true err = spec.SetMeta(meta) c.Assert(err, check.IsNil) meta, err = spec.Meta(false) c.Assert(err, check.IsNil) // Cannot set the "continuous" flag c.Check(meta.Continuous, check.Equals, false) c.Check(meta.CanBeContinuous, check.Equals, false) }
// ControlWorkSpec makes changes to a work spec that are not directly // reflected in the work spec definition. This allows work specs to // be paused or to stop generating new continuous jobs. // ControlWorkSpecOptions has a complete listing of what can be done. func (jobs *JobServer) ControlWorkSpec(workSpecName string, options map[string]interface{}) (bool, string, error) { var ( cwsOptions ControlWorkSpecOptions decoder *mapstructure.Decoder err error metadata mapstructure.Metadata workSpec coordinate.WorkSpec wsMeta coordinate.WorkSpecMeta ) workSpec, err = jobs.Namespace.WorkSpec(workSpecName) if err == nil { // We care a lot about "false" vs. not present for // these things. Manually create the decoder. config := mapstructure.DecoderConfig{ Result: &cwsOptions, Metadata: &metadata, } decoder, err = mapstructure.NewDecoder(&config) } if err == nil { err = decoder.Decode(options) } // Get the existing metadata, then change it based on what // we got provided if err == nil { wsMeta, err = workSpec.Meta(false) } if err == nil { for _, key := range metadata.Keys { switch key { case "Continuous": wsMeta.Continuous = cwsOptions.Continuous case "Status": wsMeta.Paused = cwsOptions.Status == Paused case "Weight": wsMeta.Weight = cwsOptions.Weight case "Interval": wsMeta.Interval = time.Duration(cwsOptions.Interval) * time.Second case "MaxRunning": wsMeta.MaxRunning = cwsOptions.MaxRunning } } } if err == nil { err = workSpec.SetMeta(wsMeta) } return err == nil, "", err }
func (spec *workSpec) SetMeta(meta coordinate.WorkSpecMeta) error { globalLock(spec) defer globalUnlock(spec) // Preserve immutable fields (taking advantage of meta pass-by-value) meta.CanBeContinuous = spec.meta.CanBeContinuous meta.NextWorkSpecName = spec.meta.NextWorkSpecName // If this cannot be continuous, force-clear that flag if !meta.CanBeContinuous { meta.Continuous = false } spec.meta = meta return nil }