Re: [PATCH] Use tail process to ensure line buffered output to screen and log file at the same moment... (#506664)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It is not the prettiest approach, but it works. We definitely need another thread or process to ensure the  output is line buffered and interactive %post and %pre scripts work as expected.

Martin

----- "Martin Sivak" <msivak@xxxxxxxxxx> wrote:

> ---
>  iutil.py |   84
> ++++++++++++++++++++++++++++++++++++++++++++++++++------------
>  1 files changed, 68 insertions(+), 16 deletions(-)
> 
> diff --git a/iutil.py b/iutil.py
> index ba1d0b4..0a4adfa 100644
> --- a/iutil.py
> +++ b/iutil.py
> @@ -33,6 +33,7 @@ from flags import flags
>  from constants import *
>  from rhpl.translate import _
>  import re
> +import select
>  
>  import logging
>  log = logging.getLogger("anaconda")
> @@ -81,37 +82,88 @@ def execWithRedirect(command, argv, stdin = None,
> stdout = None,
>  
>      runningLog = open("/tmp/program.log", "a")
>      runningLog.write("Running... %s\n" % ([command] + argv,))
> +   
> +    #prepare os pipes for feeding tee proceses
> +    pstdout, pstdin = os.pipe()
> +    perrout, perrin = os.pipe()
>  
>      env = os.environ.copy()
>      env.update({"LC_ALL": "C"})
>  
> +    #prepare "empty" tee proceses so we can properly detect errors
> +    proc_std = None
> +    proc_err = None
> +
>      try:
> -        proc = subprocess.Popen([command] + argv, stdin=stdin,
> -                                stdout=subprocess.PIPE,
> +        #create output pipes with logging (it needs to be different
> process to avoid deadlock and EOF detection..)
> +        proc_std = subprocess.Popen(["tee", "-a",
> "/tmp/program.log"], stdin=pstdout,
> +                                stdout=stdout,
>                                  stderr=subprocess.PIPE,
> +                                cwd=root,
> +                                env=env, bufsize = 1)
> +        
> +        proc_err = subprocess.Popen(["tee", "-a",
> "/tmp/program.log"], stdin=perrout,
> +                                stdout=stderr,
> +                                stderr=subprocess.PIPE,
> +                                cwd=root,
> +                                env=env, bufsize = 1)
> +
> +        #run the command
> +        proc = subprocess.Popen([command] + argv, stdin=stdin,
> +                                stdout=pstdin,
> +                                stderr=perrin,
>                                  preexec_fn=chroot, cwd=root,
> -                                env=env)
> +                                env=env, bufsize = 1)
> +        
> +        proc.wait()
> +
> +        #close the output pipes
> +        if proc_std:
> +            proc_std.terminate()
> +            proc_std.wait()
> +            proc_std = None
> +
> +        if proc_err:
> +            proc_err.terminate()
> +            proc_err.wait()
> +            proc_err = None
> +
> +        ret = proc.returncode
>  
> -        while True:
> -            (outStr, errStr) = proc.communicate()
> -            if outStr:
> -                os.write(stdout, outStr)
> -                runningLog.write(outStr)
> -            if errStr:
> -                os.write(stderr, errStr)
> -                runningLog.write(errStr)
>  
> -            if proc.returncode is not None:
> -                ret = proc.returncode
> -                break
>      except OSError as e:
>          errstr = "Error running %s: %s" % (command, e.strerror)
>          log.error(errstr)
> +
> +        #free descriptors
> +        os.close(pstdout)
> +        os.close(perrout)
> +        os.close(pstdin)
> +        os.close(perrin)
> +        
> +        #close the output pipes
> +        if proc_std:
> +            proc_std.terminate()
> +            proc_std.wait()
> +            proc_std = None
> +
> +        if proc_err:
> +            proc_err.terminate()
> +            proc_err.wait()
> +            proc_err = None
> +
>          runningLog.write(errstr)
>          runningLog.close()
>          raise RuntimeError, errstr
>  
>      runningLog.close()
> +
> +    #free descriptors
> +    os.close(pstdout)
> +    os.close(perrout)
> +    os.close(pstdin)
> +    os.close(perrin)
> +
>      return ret
>  
>  ## Run an external program and capture standard out.
> -- 
> 1.5.4.3

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux