// Launch an action represented by a scheduler entity, this function takes // care of submitting the action to the API and making a note of when to // attempt to retrieve the results of the action. func (e *entity) launchAction() (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("launchAction() -> %v", e) } }() // Load the action from the entity run directory actpath := path.Join(e.baseDir, "action.json") act, err := mig.ActionFromFile(actpath) if err != nil { panic(err) } act.Name = fmt.Sprintf("mig-runner: %v", e.name) cli, err := client.NewClient(ctx.ClientConf, "mig-runner") if err != nil { panic(err) } // Borrow some logic from the action generator. Set a validation // period starting in the past so our action starts immediately. window := time.Duration(-60 * time.Second) act.ValidFrom = time.Now().Add(window).UTC() exstring := defaultExpiry if e.cfg.Configuration.Expiry != "" { exstring = e.cfg.Configuration.Expiry } period, err := time.ParseDuration(exstring) if err != nil { panic(err) } // Add the window period to the desired expiry since our start // time begins in the past. period += -window act.ExpireAfter = act.ValidFrom.Add(period) act, err = cli.CompressAction(act) if err != nil { panic(err) } asig, err := cli.SignAction(act) if err != nil { panic(err) } act = asig res, err := cli.PostAction(act) if err != nil { panic(err) } mlog("%v: launched action %.0f", e.name, res.ID) // If we only dispatch this action we are done here. if e.cfg.Configuration.SendOnly { return nil } // Notify the results processor an action is in-flight re := mig.RunnerResult{} re.EntityName = e.name re.Action = res re.UsePlugin = e.cfg.Configuration.Plugin ctx.Channels.Results <- re return nil }