Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/exec: adds --stdin-input (-I) flag for input piping or manual entry #6822

Merged

Conversation

colinjlacy
Copy link
Contributor

What are the changes in this PR?

  • adds --std-in flag to exec command
  • adds test coverage to cmd/internal/exec package
  • updates exec command docs with new flag

Notes to assist PR review:

Can test with input piping, e.g. echo "{\"foo\": 8}" | opa exec ... or manual entry via Stdin.

Fixes #6538

Copy link

netlify bot commented Jun 17, 2024

Deploy Preview for openpolicyagent ready!

Name Link
🔨 Latest commit e5615d7
🔍 Latest deploy log https://app.netlify.com/sites/openpolicyagent/deploys/667c10134506130008a404a9
😎 Deploy Preview https://deploy-preview-6822--openpolicyagent.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

cmd/exec.go Outdated
@@ -78,6 +79,7 @@ e.g., opa exec --decision /foo/bar/baz ...`,
cmd.Flags().VarP(params.LogLevel, "log-level", "l", "set log level")
cmd.Flags().Var(params.LogFormat, "log-format", "set log format")
cmd.Flags().StringVar(&params.LogTimestampFormat, "log-timestamp-format", "", "set log timestamp format (OPA_LOG_TIMESTAMP_FORMAT environment variable)")
cmd.Flags().BoolVarP(&params.StdIn, "std-in", "", false, "read input from os.Stdin rather than a static file; read timeout is 30 seconds")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use the same flag as opa eval uses, please:

  -I, --stdin-input                                               read input document from stdin

}

func (sr *stdInReader) ReadInput() (string, error) {
input := make(chan string, 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who closes that channel? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

@colinjlacy colinjlacy force-pushed the issue-6538-stdin-input branch from b582237 to 294b6f3 Compare June 19, 2024 10:50
lines = append(lines, line)
}
}
}(done)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 I think the scoping rules would let you safely use done inside the go func() { ... }() body, wouldn't they?

case i := <-input:
return i, nil
case <-time.After(sr.Timeout):
done <- true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think close(done) would be more slightly more idiomatic? Closed channels return their type's zero value; but we don't care for that value anyhow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL 👍

@colinjlacy
Copy link
Contributor Author

Hey folks, I'm stuck on one aspect of this and I could use some guidance. In offline convos with @srenatus it was pointed out that trying to set a timeout on the goroutine that spawns the stdin reader creates a blocking thread that will continue to block until the main process exits. That is to say that even with the timeout in the main goroutine, prompting it to continue and not wait for the child goroutine to send back data, the child will continue to block and wait for input from stdin. That's not great as it's a known memory leak and unintentional block on further input (if further input is ever needed). So the timeout has some less-than ideal side effects.

On the other hand, as was discussed in the original issue, I'm concerned about the overall UX of adding functionality that could potentially hang indefinitely while the process awaits user input.

In order to get something in, I'm more partial to the idea of preventing the leak/block and omitting the timeout, as it doesn't look like it's possible to get around blocking reads on stdin. Any objections?

@srenatus
Copy link
Contributor

I think it's OK to not have a timeout, and use the simplest possible thing here. It's also going to be on-par with the opa eval -I. 👍

@colinjlacy colinjlacy force-pushed the issue-6538-stdin-input branch 3 times, most recently from 6af67c8 to e25b93b Compare June 25, 2024 08:07
@srenatus srenatus changed the title cmd/exec: adds --std-in flag for input piping or manual entry cmd/exec: adds --stdin-input (-I) flag for input piping or manual entry Jun 26, 2024
srenatus
srenatus previously approved these changes Jun 26, 2024
Copy link
Contributor

@srenatus srenatus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite an overhaul of our tests there, but I think it's for the better. Thanks!

There's one nitpick that you can safely ignore (t.Cleanup) but the docs should probably be regenerated to match the flag.

👏 Thanks again!

t.Fatalf("unexpected error when rewinding temp file: %q", err.Error())
}
oldStdin := os.Stdin
defer func() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit][ We could use t.Cleanup() here. But it doesn't make a difference, I believe.

@@ -618,6 +618,7 @@ opa exec <path> [<path> [...]] [flags]
--log-timestamp-format string set log timestamp format (OPA_LOG_TIMESTAMP_FORMAT environment variable)
--set stringArray override config values on the command line (use commas to specify multiple values)
--set-file stringArray override config values with files on the command line (use commas to specify multiple values)
--std-in read input from `os.Stdin` rather than a static file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be regenerated, I think?

@srenatus
Copy link
Contributor

srenatus commented Jun 26, 2024

@johanfylling can you have a quick look and merge when it's convenient, please?

Copy link
Contributor

@johanfylling johanfylling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 😃

@johanfylling johanfylling merged commit 96800d7 into open-policy-agent:main Jun 26, 2024
28 checks passed
@colinjlacy colinjlacy deleted the issue-6538-stdin-input branch June 26, 2024 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add --stdin-input flag to opa exec command
3 participants