Skip to content

Commit

Permalink
Merge pull request #31 from andywaltlova/return-json-file-with-script…
Browse files Browse the repository at this point in the history
…-stdout

Read script stdout and wrap it in required json format
  • Loading branch information
andywaltlova authored Jul 3, 2023
2 parents 38ba682 + 200c89f commit 9e1e7de
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 30 deletions.
6 changes: 6 additions & 0 deletions development/nginx/command
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
data='{"alert": false, "summary": "convert2rhel did not detect issues", "report": "", "report_json": {"foo": "bar"}}'

/usr/bin/convert2rhel --help
/usr/bin/convert2rhel --version
echo "BEGIN MARKER"
echo "$data"
echo "END MARKER"
8 changes: 4 additions & 4 deletions src/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"git.sr.ht/~spc/go-log"
)

func executeScript(fileName string) {
cmd := exec.Command("/bin/sh", fileName)
log.Debug("Cmd: ", cmd)
if err := cmd.Run(); err != nil {
func executeScript(fileName string) string {
out, err := exec.Command("/bin/sh", fileName).Output()
if err != nil {
log.Errorln("Failed to execute script: ", err)
}

log.Infoln("Bash script executed successfully.")
return string(out)
}
28 changes: 13 additions & 15 deletions src/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,12 @@ func (s *jobServer) Send(ctx context.Context, d *pb.Data) (*pb.Receipt, error) {
go func() {
log.Infoln("Writing temporary bash script.")
// Write the file contents to the temporary disk
fileName := writeFileToTemporaryDir(d.GetContent())
defer os.Remove(fileName)
scriptFileName := writeFileToTemporaryDir(d.GetContent())
defer os.Remove(scriptFileName)

log.Infoln("Executing bash script located at: ", fileName)
log.Infoln("Executing and reading output of bash script located at: ", scriptFileName)
// Execute the script we wrote to the file
executeScript(fileName)

// TODO(r0x0d): Remove this after PoC. We will be reading the output
// that comes from the executeScript function, as we want what is in
// the stdout to make it more generic, instead of relying on reading an
// output file in the system. https://issues.redhat.com/browse/HMS-2005
reportFile := "/var/log/convert2rhel/convert2rhel-report.json"
log.Infoln("Reading output file at: ", reportFile)
fileContent, boundary := readOutputFile(reportFile)
commandOutput := executeScript(scriptFileName)

// Dial the Dispatcher and call "Finish"
conn, err := grpc.Dial(yggdDispatchSocketAddr, grpc.WithInsecure())
Expand All @@ -53,10 +45,14 @@ func (s *jobServer) Send(ctx context.Context, d *pb.Data) (*pb.Receipt, error) {
defer cancel()

// Create a data message to send back to the dispatcher.
// Call "Send"
log.Infof("Creating payload for message %s", d.GetMessageId())

correlationID := d.GetMetadata()["correlation_id"]
metadataContentType := d.GetMetadata()["return_content_type"]
fileContent, boundary := getOutputFile(scriptFileName, commandOutput, correlationID, metadataContentType)

var data *pb.Data
log.Infof("Sending message to %s", d.GetMessageId())
if fileContent != nil {
if commandOutput != "" && fileContent != nil {
contentType := fmt.Sprintf("multipart/form-data; boundary=%s", boundary)
log.Infof("Sending message to %s", d.GetMessageId())
data = &pb.Data{
Expand All @@ -75,6 +71,8 @@ func (s *jobServer) Send(ctx context.Context, d *pb.Data) (*pb.Receipt, error) {
}
}

// Call "Send"
log.Infof("Sending message to %s", d.GetMessageId())
log.Infoln("pb.Data message: ", data)
if _, err := c.Send(ctx, data); err != nil {
log.Error(err)
Expand Down
26 changes: 15 additions & 11 deletions src/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
Expand Down Expand Up @@ -35,31 +36,34 @@ func writeFileToTemporaryDir(data []byte) string {
return fileName
}

func readOutputFile(filePath string) (*bytes.Buffer, string) {
log.Infoln("Reading file at:", filePath)
file, err := os.Open(filePath)
type jsonResponseFormat struct {
CorrelationID string `json:"correlation_id"`
Stdout string `json:"stdout"`
}

func getOutputFile(scriptFileName string, stdout string, correlationID string, contentType string) (*bytes.Buffer, string) {
payloadData := jsonResponseFormat{CorrelationID: correlationID, Stdout: stdout}
jsonPayload, err := json.Marshal(payloadData)
if err != nil {
log.Infoln("Failed to read output file: ", err)
return nil, ""
log.Errorln("Failed to marshal paylod data: ", err)
}
reader := bytes.NewReader(jsonPayload)

log.Infoln("Writing form-data for file: ", filePath)
log.Infoln("Writing form-data for executed script: ", scriptFileName)
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

h := make(textproto.MIMEHeader)
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, "file", "rhc-worker-bash-output.tar.gz"))

// FIXME: parse it from metadata
h.Set("Content-Type", "application/vnd.redhat.tasks.filename+tgz")
h.Set("Content-Type", contentType)

part, err := writer.CreatePart(h)
if err != nil {
log.Errorln("Couldn't create form-file: ", err)
}
_, err = io.Copy(part, file)
_, err = io.Copy(part, reader)
if err != nil {
log.Errorln("Failed to copy contents to file: ", err)
log.Errorln("Failed to write json with script stdout to file: ", err)
}

writer.Close()
Expand Down

0 comments on commit 9e1e7de

Please sign in to comment.