Merge pull request #18657 from arizvisa/GH-18120

Added the "--out" parameter and fixed an issue with "--noout" which prevented stdout from being written to.
This commit is contained in:
OpenShift Merge Robot
2023-06-05 14:34:21 -04:00
committed by GitHub
5 changed files with 105 additions and 17 deletions

View File

@ -48,12 +48,8 @@ var (
)
var (
runOpts = entities.ContainerRunOptions{
OutputStream: os.Stdout,
InputStream: os.Stdin,
ErrorStream: os.Stderr,
}
runRmi bool
runOpts entities.ContainerRunOptions
runRmi bool
)
func runFlags(cmd *cobra.Command) {
@ -154,6 +150,11 @@ func run(cmd *cobra.Command, args []string) error {
}
}
// First set the default streams before they get modified by any flags.
runOpts.OutputStream = os.Stdout
runOpts.InputStream = os.Stdin
runOpts.ErrorStream = os.Stderr
// If -i is not set, clear stdin
if !cliVals.Interactive {
runOpts.InputStream = nil

View File

@ -79,17 +79,24 @@ var (
useSyslog bool
requireCleanup = true
noOut = false
// Defaults for capturing/redirecting the command output since (the) cobra is
// global-hungry and doesn't allow you to attach anything that allows us to
// transform the noStdout BoolVar to a string that we can assign to useStdout.
noStdout = false
useStdout = ""
)
func init() {
// Hooks are called before PersistentPreRunE()
// Hooks are called before PersistentPreRunE(). These hooks affect global
// state and are executed after processing the command-line, but before
// actually running the command.
cobra.OnInitialize(
stdOutHook, // Caution, this hook redirects stdout and output from any following hooks may be affected.
loggingHook,
syslogHook,
earlyInitHook,
configHook,
noOutHook,
)
rootFlags(rootCmd, registry.PodmanConfig())
@ -376,10 +383,23 @@ func loggingHook() {
}
}
func noOutHook() {
if noOut {
null, _ := os.Open(os.DevNull)
os.Stdout = null
// used for capturing podman's formatted output to some file as per the -out and -noout flags.
func stdOutHook() {
// if noStdOut was specified, then assign /dev/null as the standard file for output.
if noStdout {
useStdout = os.DevNull
}
// if we were given a filename for output, then open that and use it. we end up leaking
// the file since it's intended to be in scope as long as our process is running.
if useStdout != "" {
if fd, err := os.OpenFile(useStdout, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm); err == nil {
os.Stdout = fd
// if we couldn't open the file for write, then just bail with an error.
} else {
fmt.Fprintf(os.Stderr, "unable to open file for standard output: %s\n", err.Error())
os.Exit(1)
}
}
}
@ -415,7 +435,14 @@ func rootFlags(cmd *cobra.Command, podmanConfig *entities.PodmanConfig) {
lFlags.StringVar(&podmanConfig.Identity, identityFlagName, ident, "path to SSH identity file, (CONTAINER_SSHKEY)")
_ = cmd.RegisterFlagCompletionFunc(identityFlagName, completion.AutocompleteDefault)
lFlags.BoolVar(&noOut, "noout", false, "do not output to stdout")
// Flags that control or influence any kind of output.
outFlagName := "out"
lFlags.StringVar(&useStdout, outFlagName, "", "Send output (stdout) from podman to a file")
_ = cmd.RegisterFlagCompletionFunc(outFlagName, completion.AutocompleteDefault)
lFlags.BoolVar(&noStdout, "noout", false, "do not output to stdout")
_ = lFlags.MarkHidden("noout") // Superseded by --out
lFlags.BoolVarP(&podmanConfig.Remote, "remote", "r", registry.IsRemote(), "Access remote Podman service")
pFlags := cmd.PersistentFlags()
if registry.IsRemote() {

View File

@ -95,9 +95,8 @@ and "$graphroot/networks" as rootless.
For the CNI backend the default is "/etc/cni/net.d" as root
and "$HOME/.config/cni/net.d" as rootless. CNI is deprecated from Podman in the future, use netavark.
#### **--noout**
Redirect stdout to /dev/null. This command prevents all stdout from the Podman command. The **--noout** option is not block stderr or stdout from containers.
#### **--out**=*path*
Redirect the output of podman to the specified path without affecting the container output or its logs. This parameter can be used to capture the output from any of podman's commands directly into a file and enable suppression of podman's output by specifying /dev/null as the path. To explicitly disable the container logging, the **--log-driver** option should be used.
#### **--remote**, **-r**
When true, access to the Podman service is remote. Defaults to false.

View File

@ -239,6 +239,36 @@ run_podman --noout system connection ls
is "$output" "" "output should be empty"
}
# Tests --noout to ensure that the output fd can be written to.
@test "podman --noout is actually writing to /dev/null" {
skip_if_remote "unshare only works locally"
skip_if_not_rootless "unshare requires rootless"
run_podman --noout unshare ls
is "$output" "" "output should be empty"
}
@test "podman version --out writes matching version to a json" {
run_podman version
# copypasta from version check. we're doing this to extract the version.
if expr "${lines[0]}" : "Client: *" >/dev/null; then
lines=("${lines[@]:1}")
fi
# get the version number so that we have something to compare with.
IFS=: read version_key version_number <<<"${lines[0]}"
is "$version_key" "Version" "Version line"
# now we can output everything as some json. we can't use PODMAN_TMPDIR since basic_setup
# isn't being used in setup() due to being unable to trust podman-images or podman-rm.
outfile=$(mktemp -p ${BATS_TEST_TMPDIR} veroutXXXXXXXX)
run_podman --out $outfile version -f json
# extract the version from the file.
run jq -r --arg field "$version_key" '.Client | .[$field]' $outfile
is "$output" ${version_number} "Version matches"
}
@test "podman - shutdown engines" {
run_podman --log-level=debug run --rm $IMAGE true
is "$output" ".*Shutting down engines.*"

View File

@ -518,6 +518,37 @@ json-file | f
is "$output" "" "output should be empty"
}
@test "podman --out run should save the container id" {
outfile=${PODMAN_TMPDIR}/out-results
# first we'll need to run something, write its output to a file, and then read its contents.
run_podman --out $outfile run -d --name test $IMAGE echo hola
is "$output" "" "output should be redirected"
run_podman wait test
# compare the container id against the one in the file
run_podman container inspect --format '{{.Id}}' test
is "$output" "$(<$outfile)" "container id should match"
run_podman --out /dev/null rm test
is "$output" "" "output should be empty"
}
@test "podman --out create should save the container id" {
outfile=${PODMAN_TMPDIR}/out-results
# first we'll need to run something, write its output to a file, and then read its contents.
run_podman --out $outfile create --name test $IMAGE echo hola
is "$output" "" "output should be redirected"
# compare the container id against the one in the file
run_podman container inspect --format '{{.Id}}' test
is "$output" "$(<$outfile)" "container id should match"
run_podman --out /dev/null rm test
is "$output" "" "output should be empty"
}
# Regression test for issue #8082
@test "podman run : look up correct image name" {
# Create a 2nd tag for the local image. Force to lower case, and apply it.