invirt.common: give clearer error message on missing config variable
[invirt/packages/invirt-base.git] / python / invirt / remctl.py
1 """
2 Functions to perform remctls.
3 """
4
5 from invirt.common import CodeError
6 import subprocess
7 import sys
8 from socket import getfqdn
9
10 def kinit(principal=None, keytab=None):
11     """Kinit with a given username and keytab"""
12     if principal is None:
13         principal = 'daemon/' + getfqdn()
14     if keytab is None:
15         keytab = '/etc/invirt/keytab'
16     p = subprocess.Popen(['kinit', "-k", "-t", keytab, principal],
17                          stderr=subprocess.PIPE)
18     e = p.wait()
19     if e:
20         raise CodeError("Error %s in kinit: %s" % (e, p.stderr.read()))
21
22 def checkKinit(principal=None, keytab=None):
23     """If we lack tickets, kinit."""
24     p = subprocess.Popen(['klist', '-s'])
25     if p.wait():
26         kinit(principal, keytab)
27
28 def remctl(host, *args, **kws):
29     """Perform a remctl and return the output.
30
31     kinits if necessary, and outputs errors to stderr.
32     """
33     checkKinit(kws.get('principal'), kws.get('keytab'))
34     p = subprocess.Popen(['remctl', host]
35                          + list(args),
36                          stdout=subprocess.PIPE,
37                          stderr=subprocess.PIPE)
38     v = p.wait()
39     if kws.get('err'):
40         return p.stdout.read(), p.stderr.read()
41     if v:
42         print >> sys.stderr, 'Error', v, 'on remctl', args, ':'
43         print >> sys.stderr, p.stderr.read()
44         raise CodeError('ERROR on remctl')
45     return p.stdout.read()