func (mc *MockCommand) Execute(logger plugin.Logger, pluginCom plugin.PluginCommunicator, conf *model.TaskConfig, stop chan bool) error { resp, err := pluginCom.TaskGetJSON(fmt.Sprintf("blah/%s/%d", mc.Param1, mc.Param2)) if resp != nil { defer resp.Body.Close() } if resp == nil { return fmt.Errorf("Received nil HTTP response from api server") } jsonReply := map[string]string{} err = util.ReadJSONInto(resp.Body, &jsonReply) if err != nil { return err } if resp.StatusCode != http.StatusOK { return fmt.Errorf("Got bad status code from API response: %v, body: %v", resp.StatusCode, jsonReply) } expectedEchoReply := fmt.Sprintf("%v/%v/%v", mc.Param1, mc.Param2, conf.Task.Id) if jsonReply["echo"] != expectedEchoReply { return fmt.Errorf("Wrong echo reply! Wanted %v, got %v", expectedEchoReply, jsonReply["echo"]) } return nil }
func (jgc *JSONHistoryCommand) Execute(log plugin.Logger, com plugin.PluginCommunicator, conf *model.TaskConfig, stop chan bool) error { err := plugin.ExpandValues(jgc, conf.Expansions) if err != nil { return err } if jgc.File == "" { return fmt.Errorf("'file' param must not be blank") } if jgc.DataName == "" { return fmt.Errorf("'name' param must not be blank") } if jgc.TaskName == "" { return fmt.Errorf("'task' param must not be blank") } if jgc.File != "" && !filepath.IsAbs(jgc.File) { jgc.File = filepath.Join(conf.WorkDir, jgc.File) } endpoint := fmt.Sprintf("history/%s/%s", jgc.TaskName, jgc.DataName) if jgc.Tags { endpoint = fmt.Sprintf("tags/%s/%s", jgc.TaskName, jgc.DataName) } retriableGet := util.RetriableFunc( func() error { resp, err := com.TaskGetJSON(endpoint) if resp != nil { defer resp.Body.Close() } if err != nil { //Some generic error trying to connect - try again log.LogExecution(slogger.WARN, "Error connecting to API server: %v", err) return util.RetriableError{err} } if resp.StatusCode == http.StatusOK { jsonBytes, err := ioutil.ReadAll(resp.Body) if err != nil { return err } return ioutil.WriteFile(jgc.File, jsonBytes, 0755) } if resp.StatusCode != http.StatusOK { if resp.StatusCode == http.StatusNotFound { return fmt.Errorf("No JSON data found") } return util.RetriableError{fmt.Errorf("unexpected status code %v", resp.StatusCode)} } return nil }, ) _, err = util.Retry(retriableGet, 10, 3*time.Second) return err }
// getPatchContents() dereferences any patch files that are stored externally, fetching them from // the API server, and setting them into the patch object. func (gapc GitApplyPatchCommand) getPatchContents(conf *model.TaskConfig, com plugin.PluginCommunicator, log plugin.Logger, p *patch.Patch) error { for i, patchPart := range p.Patches { // If the patch isn't stored externally, no need to do anything. if patchPart.PatchSet.PatchFileId == "" { continue } // otherwise, fetch the contents and load it into the patch object log.LogExecution(slogger.INFO, "Fetching patch contents for %v", patchPart.PatchSet.PatchFileId) var result []byte retriableGet := util.RetriableFunc( func() error { resp, err := com.TaskGetJSON(fmt.Sprintf("%s/%s", GitPatchFilePath, patchPart.PatchSet.PatchFileId)) if resp != nil { defer resp.Body.Close() } if err != nil { //Some generic error trying to connect - try again log.LogExecution(slogger.WARN, "Error connecting to API server: %v", err) return util.RetriableError{err} } if resp != nil && resp.StatusCode != http.StatusOK { log.LogExecution(slogger.WARN, "Unexpected status code %v, retrying", resp.StatusCode) resp.Body.Close() return util.RetriableError{fmt.Errorf("Unexpected status code %v", resp.StatusCode)} } result, err = ioutil.ReadAll(resp.Body) if err != nil { return err } return nil }) _, err := util.RetryArithmeticBackoff(retriableGet, 5, 5*time.Second) if err != nil { return err } p.Patches[i].PatchSet.Patch = string(result) } return nil }
// Load performs a GET on /manifest/load func (mfc *ManifestLoadCommand) Load(log plugin.Logger, pluginCom plugin.PluginCommunicator, conf *model.TaskConfig) error { var loadedManifest *manifest.Manifest var err error retriableGet := util.RetriableFunc( func() error { resp, err := pluginCom.TaskGetJSON(ManifestLoadAPIEndpoint) if resp != nil { defer resp.Body.Close() } if err != nil { //Some generic error trying to connect - try again log.LogExecution(slogger.WARN, "Error connecting to API server: %v", err) return util.RetriableError{err} } if resp != nil && resp.StatusCode != http.StatusOK { log.LogExecution(slogger.WARN, "Unexpected status code %v, retrying", resp.StatusCode) return util.RetriableError{fmt.Errorf("Unexpected status code %v", resp.StatusCode)} } err = util.ReadJSONInto(resp.Body, &loadedManifest) if err != nil { return err } return nil }) _, err = util.RetryArithmeticBackoff(retriableGet, 5, 5*time.Second) if err != nil { return err } if loadedManifest == nil { return fmt.Errorf("Manifest is empty") } mfc.updateExpansions(loadedManifest, conf) return nil }
// GetPatch tries to get the patch data from the server in json format, // and unmarhals it into a patch struct. The GET request is attempted // multiple times upon failure. func (gapc GitApplyPatchCommand) GetPatch(conf *model.TaskConfig, pluginCom plugin.PluginCommunicator, pluginLogger plugin.Logger) (*patch.Patch, error) { patch := &patch.Patch{} retriableGet := util.RetriableFunc( func() error { resp, err := pluginCom.TaskGetJSON(GitPatchPath) if resp != nil { defer resp.Body.Close() } if err != nil { //Some generic error trying to connect - try again pluginLogger.LogExecution(slogger.WARN, "Error connecting to API server: %v", err) return util.RetriableError{err} } if resp != nil && resp.StatusCode == http.StatusNotFound { //nothing broke, but no patch was found for task Id - no retry body, err := ioutil.ReadAll(resp.Body) if err != nil { pluginLogger.LogExecution(slogger.ERROR, "Error reading response body") } msg := fmt.Sprintf("no patch found for task: %v", string(body)) pluginLogger.LogExecution(slogger.WARN, msg) return fmt.Errorf(msg) } if resp != nil && resp.StatusCode == http.StatusInternalServerError { //something went wrong in api server body, err := ioutil.ReadAll(resp.Body) if err != nil { pluginLogger.LogExecution(slogger.ERROR, "Error reading response body") } msg := fmt.Sprintf("error fetching patch from server: %v", string(body)) pluginLogger.LogExecution(slogger.WARN, msg) return util.RetriableError{ fmt.Errorf(msg), } } if resp != nil && resp.StatusCode == http.StatusConflict { //wrong secret body, err := ioutil.ReadAll(resp.Body) if err != nil { pluginLogger.LogExecution(slogger.ERROR, "Error reading response body") } msg := fmt.Sprintf("secret conflict: %v", string(body)) pluginLogger.LogExecution(slogger.ERROR, msg) return fmt.Errorf(msg) } if resp == nil { pluginLogger.LogExecution(slogger.WARN, "Empty response from API server") return util.RetriableError{fmt.Errorf("empty response")} } else { err = util.ReadJSONInto(resp.Body, patch) if err != nil { pluginLogger.LogExecution(slogger.ERROR, "Error reading json into patch struct: %v", err) return util.RetriableError{err} } return nil } }, ) retryFail, err := util.RetryArithmeticBackoff(retriableGet, 5, 5*time.Second) if retryFail { return nil, fmt.Errorf("getting patch failed after %v tries: %v", 10, err) } if err != nil { return nil, fmt.Errorf("getting patch failed: %v", err) } return patch, nil }