func/forkbomb.py | 5 +- func/index_db.py | 11 ++---- func/jobthing.py | 2 - func/overlord/client.py | 8 ++++ func/overlord/inventory.py | 2 - func/utils.py | 76 +++++++++++++++++++++++++++------------------ scripts/func-yum | 3 + 7 files changed, 66 insertions(+), 41 deletions(-) New commits: commit c88ff0a5ff249b6e24bc32724fbe7690e5e797a9 Author: David Ward <david.ward@xxxxxxxxxx> Date: Wed Mar 16 12:31:35 2011 -0400 Until recently, NetworkManager modified /etc/hosts and added the (real) hostname as an alias to the loopback address 127.0.0.1, and also as an alias to the IP address of the interface(s) it managed. In this situation, func actually detected the hostname as "127.0.0.1", which was then used by certmaster as the key name in the certificate. Even though the current NetworkManager does not touch /etc/hosts, func should be able to handle this case. This change includes the needed fixes to get_hostname_by_route. Other code in this function has been edited to improve clarity. diff --git a/func/utils.py b/func/utils.py index 64a7a83..8a7e9d5 100644 --- a/func/utils.py +++ b/func/utils.py @@ -85,8 +85,6 @@ def get_hostname_by_route(): """ # FIXME: this code ignores http proxies (which granted, we don't # support elsewhere either. - hostname = None - ip = None minion_config_file = '/etc/func/minion.conf' minion_config = read_config(minion_config_file, FuncdConfig) @@ -103,50 +101,37 @@ def get_hostname_by_route(): server = cm_config.certmaster port = cm_config.certmaster_port + s = socket.socket() + s.settimeout(5) + s.connect_ex((server, port)) + (intf, port) = s.getsockname() + s.close() + try: - s = socket.socket() - s.settimeout(5) - s.connect((server, port)) - (intf, port) = s.getsockname() - # this can fail if there is no reverse DNS available - intf_hostname = socket.gethostbyaddr(intf)[0] - ip = socket.gethostbyname(intf_hostname) - # not talking via localhost? good enough... - if ip != '127.0.0.1': - s.close() - return intf_hostname.lower() + return socket.gethostbyaddr(intf)[0] except: - s.close() - # something failed, reverse dns, etc + pass # try to find the hostname of the ip we're listening on if minion_config.listen_addr: try: - (hostname, aliases, ips) = socket.gethostbyaddr(minion_config.listen_addr) + return socket.gethostbyaddr(minion_config.listen_addr)[0] except: - hostname = None + pass # in an ideal world, this would return exactly what we want: the most meaningful hostname # for a system, but that is often not that case - if hostname is None: - hostname = socket.gethostname() - - # "localhost" is a really crappy hostname, so is pretty much anything attached - # to 127.0.0.1, so try for something better try: + hostname = socket.gethostname() ip = socket.gethostbyname(hostname) + if ip != "127.0.0.1" and ip != "::1": + return hostname.lower() except: - hostname = None - - # non loopback is about as good as we can do for a guess - if ip != "127.0.0.1" and hostname is not None: - return hostname.lower() - - + pass # all else has failed to get a good hostname, so just return # an ip address - return socket.gethostbyname(socket.gethostname()).lower() # yes I know it's an ip but I don't trust anything + return intf def find_files_by_hostname(hostglob, filepath, fileext=''): """look for files in the given filepath with the given extension that commit 03c9bf7119fb114f7d618b9449660d22cf2a53f8 Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Wed Mar 16 12:23:31 2011 -0400 one more place where our db-creation perms were wrong diff --git a/func/forkbomb.py b/func/forkbomb.py index 13e6a4e..c00c710 100644 --- a/func/forkbomb.py +++ b/func/forkbomb.py @@ -42,7 +42,7 @@ def __access_buckets(filename,clear,new_key=None,new_value=None): handle = open(filename,"w") fcntl.flock(handle.fileno(), fcntl.LOCK_EX) - internal_db = dbm.open(filename, 'c', 0644 ) + internal_db = dbm.open(filename, 'c', 0600 ) storage = shelve.Shelf(internal_db) if clear: commit 60a42b4258e651ee6139afd8b19b037c384b08f6 Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Wed Mar 16 12:21:37 2011 -0400 don't output hostnames/results from empty updates data from func-yum list updates diff --git a/scripts/func-yum b/scripts/func-yum index e2374bb..3ed9390 100755 --- a/scripts/func-yum +++ b/scripts/func-yum @@ -548,6 +548,9 @@ def main(args): except FYError, e: errorprint(str(e)) else: + if item == 'updates': # don't print out empty update results + if not info: + continue print '%s %s:' % (hn, item) print info print '' commit a18cb865ba6f97e5d789d5713e8b678fe5ec7ac7 Author: Hany Fahim <hany.fahim@xxxxxxxxx> Date: Wed Mar 16 11:27:42 2011 -0400 when we encounter a downed host, don't break, continue diff --git a/func/overlord/inventory.py b/func/overlord/inventory.py index df2fcbf..e424087 100644 --- a/func/overlord/inventory.py +++ b/func/overlord/inventory.py @@ -88,7 +88,7 @@ class FuncInventory(object): if utils.is_error(methods): sys.stderr.write("-- connection refused: %s\n" % host) - break + continue for each_method in methods: commit 166914400ec95b907205d02e66d8999c0e90c2ee Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Mon Mar 14 17:31:02 2011 -0400 make sure ourdbs are always 600 diff --git a/func/index_db.py b/func/index_db.py index 86e96f8..c85dfe4 100644 --- a/func/index_db.py +++ b/func/index_db.py @@ -34,7 +34,7 @@ class IndexDb(object): return False fcntl.flock(self.__handle.fileno(), fcntl.LOCK_EX) - internal_db = dbm.open(filename, 'c', 0644 ) + internal_db = dbm.open(filename, 'c', 0600 ) self.__storage = shelve.Shelf(internal_db) return True commit 4dadc90ba1e414abb5a92f7367bc6570b2329026 Merge: a766dec b47938a Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Mon Mar 14 17:29:22 2011 -0400 Merge branch 'master' of ssh://git.fedorahosted.org/git/func * 'master' of ssh://git.fedorahosted.org/git/func: (3 commits) Fixed help message in func-command to display \n instead of an actual new line ... commit a766decd77a86e56e299d19af2fb61b37c210a1a Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Thu Mar 10 12:22:52 2011 -0500 make sure we use proper tempdirs and work correctly for users who are not root and cannot access the minion dirs - in certain situations this facilitates non-root people with proper keys/certs using func and being able to track async jobs sanely. diff --git a/func/forkbomb.py b/func/forkbomb.py index d682300..13e6a4e 100644 --- a/func/forkbomb.py +++ b/func/forkbomb.py @@ -20,9 +20,10 @@ import dbm import sys import tempfile import fcntl +from func import utils DEFAULT_FORKS = 4 -DEFAULT_CACHE_DIR = "/var/lib/func" +DEFAULT_CACHE_DIR = utils.getCacheDir() def __get_storage(dir): """ diff --git a/func/index_db.py b/func/index_db.py index 51d7c0d..86e96f8 100644 --- a/func/index_db.py +++ b/func/index_db.py @@ -1,8 +1,8 @@ import shelve import dbm import fcntl +from func import utils -MY_STORE = "/var/lib/func" INTERNAL_DB_FILE = "log_matcher" class IndexDb(object): @@ -19,17 +19,14 @@ class IndexDb(object): """ self.__storage = None self.__handle = None - self.__dir = dir + self.__dir = utils.getCacheDir() def __load_index(self): """ Gets the store object for that instance """ import os - if not self.__dir or not os.path.exists(self.__dir): - filename=os.path.join(MY_STORE,INTERNAL_DB_FILE) - else: - filename=os.path.join(self.__dir,INTERNAL_DB_FILE) + filename=os.path.join(self.__dir,INTERNAL_DB_FILE) try: self.__handle = open(filename,self.__mode) except IOError, e: diff --git a/func/jobthing.py b/func/jobthing.py index 11de4c6..c75ee00 100644 --- a/func/jobthing.py +++ b/func/jobthing.py @@ -37,7 +37,7 @@ JOB_ID_REMOTE_ERROR = 4 RETAIN_INTERVAL = 60 * 60 # where to store the internal job id database -CACHE_DIR = "/var/lib/func" +CACHE_DIR = utils.getCacheDir() def __update_status(jobid, status, results, clear=False): return __access_status(jobid=jobid, status=status, results=results, write=True) diff --git a/func/overlord/client.py b/func/overlord/client.py index 2d0aba0..80df7fd 100644 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -157,6 +157,14 @@ class Minions(object): return tmp_hosts,tmp_certs else: each_gloob = shortest_path[0] + + if not os.access(self.cm_config.certroot, os.R_OK): + if self.overlord_config.allow_unknown_minions: + tmp_hosts.add(each_gloob) + else: + sys.stderr.write("Cannot read certs dir: %s and cannot use unknown minion\n" % (self.cm_config.certroot)) + + return tmp_hosts,tmp_certs #actual_gloob = "%s/%s.%s" % (self.cm_config.certroot, each_gloob, self.cm_config.cert_extension) certs = func_utils.find_files_by_hostname(each_gloob, self.cm_config.certroot, self.cm_config.cert_extension) diff --git a/func/utils.py b/func/utils.py index fd456c1..64a7a83 100644 --- a/func/utils.py +++ b/func/utils.py @@ -12,11 +12,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import inspect import os +import pwd import socket import string import sys import re import fnmatch +import tempfile +import glob +from stat import * + from certmaster.config import read_config from certmaster.commonconfig import MinionConfig @@ -215,6 +220,32 @@ def re_glob(s): if _re_compiled_glob_match is None: _re_compiled_glob_match = re.compile('[*?]|\[.+\]').search return _re_compiled_glob_match(s) + +def getCacheDir(tmpdir='/var/tmp', reuse=True, prefix='func-'): + """return a path to a valid and safe cachedir - only used when not running + as root or when --tempcache is set""" + + uid = os.geteuid() + try: + usertup = pwd.getpwuid(uid) + username = usertup[0] + except KeyError: + return None # if it returns None then, well, it's bollocksed + + if reuse: + # check for /var/tmp/func-username-* - + prefix = '%s%s-' % (prefix, username) + dirpath = '%s/%s*' % (tmpdir, prefix) + cachedirs = sorted(glob.glob(dirpath)) + for thisdir in cachedirs: + stats = os.lstat(thisdir) + if S_ISDIR(stats[0]) and S_IMODE(stats[0]) == 448 and stats[4] == uid: + return thisdir + + # make the dir (tempfile.mkdtemp()) + cachedir = tempfile.mkdtemp(prefix=prefix, dir=tmpdir) + return cachedir + #################### PROGRESS BAR ################################## # The code below can be used for progress bar purposes as we will do _______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list