make stdin read from /dev/null for all cloud-init programs (LP: #903993)

the cloud-init programs are never intended to run interactively.
Some programs were being run via subprocess, and would notice that their
input was attached to a terminal (/dev/console).   As a result, they
they would try to prompt the user for input (apt-add-repository)

This change simply re-opens standard input as /dev/null so any
subprocesses will not end up blocking on input.
This commit is contained in:
Scott Moser 2011-12-19 17:02:54 -05:00
commit 11dd718bcc
5 changed files with 21 additions and 0 deletions

View File

@ -8,6 +8,7 @@
- support setting of Acquire::HTTP::Proxy via 'apt_proxy'
- DataSourceEc2: more resilliant to slow metadata service
- config change: 'retries' dropped, 'max_wait' added, timeout increased
- close stdin in all cloud-init programs that are launched at boot (LP: #903993)
0.6.2:
- fix bug where update was not done unless update was explicitly set.
It would not be run if 'upgrade' or packages were set to be installed

View File

@ -35,6 +35,8 @@ def main():
# read cloud config jobs from config (builtin -> system)
# and run all in order
util.close_stdin()
modename = "config"
if len(sys.argv) < 2:

View File

@ -25,6 +25,8 @@ def Usage(out = sys.stdout):
out.write("Usage: cloud-init-run-module freq sem-name mod-name [args]\n")
def main():
util.close_stdin()
# expect to be called with
# <freq> <semaphore-name> <module-name> args
if len(sys.argv) < 4:

View File

@ -34,6 +34,8 @@ def warn(wstr):
sys.stderr.write("WARN:%s" % wstr)
def main():
util.close_stdin()
cmds = ( "start", "start-local" )
deps = { "start" : ( ds.DEP_FILESYSTEM, ds.DEP_NETWORK ),
"start-local" : ( ds.DEP_FILESYSTEM, ) }

View File

@ -26,6 +26,7 @@ import urllib
import logging
import re
import socket
import sys
import time
import traceback
import urlparse
@ -523,3 +524,16 @@ def search_for_mirror(candidates):
raise
return None
def close_stdin():
"""
reopen stdin as /dev/null so even subprocesses or other os level things get
/dev/null as input.
if _CLOUD_INIT_SAVE_STDIN is set in environment to a non empty or '0' value
then input will not be closed (only useful potentially for debugging).
"""
if os.environ.get("_CLOUD_INIT_SAVE_STDIN") in ("", "0", False):
return
with open(os.devnull) as fp:
os.dup2(fp.fileno(), sys.stdin.fileno())