|
Lines 31-36
Link Here
|
| 31 |
# /usr/share/common-licenses/AGPL-3; if not, see |
31 |
# /usr/share/common-licenses/AGPL-3; if not, see |
| 32 |
# <http://www.gnu.org/licenses/>. |
32 |
# <http://www.gnu.org/licenses/>. |
| 33 |
|
33 |
|
|
|
34 |
from __future__ import print_function |
| 35 |
from argparse import ArgumentParser |
| 34 |
import os |
36 |
import os |
| 35 |
import univention.config_registry |
37 |
import univention.config_registry |
| 36 |
import ldap |
38 |
import ldap |
|
Lines 38-49
import univention.uldap
Link Here
|
| 38 |
import sys |
40 |
import sys |
| 39 |
import subprocess |
41 |
import subprocess |
| 40 |
import shlex |
42 |
import shlex |
| 41 |
import getopt |
43 |
from io import StringIO |
| 42 |
|
44 |
|
| 43 |
configRegistry = univention.config_registry.ConfigRegistry() |
45 |
configRegistry = univention.config_registry.ConfigRegistry() |
| 44 |
configRegistry.load() |
46 |
configRegistry.load() |
| 45 |
verbose = False |
47 |
verbose = False |
| 46 |
simulate = False |
|
|
| 47 |
|
48 |
|
| 48 |
ldap_hostdn = configRegistry.get('ldap/hostdn') |
49 |
ldap_hostdn = configRegistry.get('ldap/hostdn') |
| 49 |
|
50 |
|
|
Lines 53-66
MAGIC_LDAP = '#LDAP Entry DN:'
Link Here
|
| 53 |
def debug(msg, out=sys.stderr): |
54 |
def debug(msg, out=sys.stderr): |
| 54 |
"""Print verbose information 'msg' to 'out'.""" |
55 |
"""Print verbose information 'msg' to 'out'.""" |
| 55 |
if verbose: |
56 |
if verbose: |
| 56 |
print >>out, msg, |
57 |
print(msg, end=' ', file=out) |
| 57 |
|
58 |
|
| 58 |
|
59 |
|
| 59 |
def exit(result, message=None): |
60 |
def exit(result, message=None): |
| 60 |
"""Exit with optional error message.""" |
61 |
"""Exit with optional error message.""" |
| 61 |
script = os.path.basename(sys.argv[0]) |
62 |
script = os.path.basename(sys.argv[0]) |
| 62 |
if message: |
63 |
if message: |
| 63 |
print >>sys.stderr, '%s: %s' % (script, message) |
64 |
print('%s: %s' % (script, message), file=sys.stderr) |
| 64 |
sys.exit(result) |
65 |
sys.exit(result) |
| 65 |
|
66 |
|
| 66 |
|
67 |
|
|
Lines 69-75
def query_policy(dn):
Link Here
|
| 69 |
nfsmount = set() |
70 |
nfsmount = set() |
| 70 |
debug('Retrieving policy for %s...\n' % dn) |
71 |
debug('Retrieving policy for %s...\n' % dn) |
| 71 |
try: |
72 |
try: |
| 72 |
p = subprocess.Popen(['univention_policy_result', '-D', ldap_hostdn, '-y', '/etc/machine.secret', '-s', dn], shell=False, stdout=subprocess.PIPE) |
73 |
p = subprocess.Popen(['univention_policy_result', '-D', ldap_hostdn, '-y', '/etc/machine.secret', '-s', dn], stdout=subprocess.PIPE) |
| 73 |
stdout, stderr = p.communicate() |
74 |
stdout, stderr = p.communicate() |
| 74 |
except OSError: |
75 |
except OSError: |
| 75 |
exit(1, "FAIL: failed to execute `univention_policy_result %s'" % dn) |
76 |
exit(1, "FAIL: failed to execute `univention_policy_result %s'" % dn) |
|
Lines 84-121
def query_policy(dn):
Link Here
|
| 84 |
return nfsmount |
85 |
return nfsmount |
| 85 |
|
86 |
|
| 86 |
|
87 |
|
| 87 |
def usage(out=sys.stdout): |
|
|
| 88 |
"""Output usage message.""" |
| 89 |
print >>out, 'syntax: nfsmounts [-h] [-v]' |
| 90 |
print >>out, ' -h, --help print this help' |
| 91 |
print >>out, ' -s, --simulate simulate update and just show actions' |
| 92 |
print >>out, ' -v, --verbose print verbose information' |
| 93 |
print >>out, '' |
| 94 |
|
| 95 |
|
| 96 |
def main(): |
88 |
def main(): |
| 97 |
# parse command line |
89 |
# parse command line |
| 98 |
try: |
90 |
parser = ArgumentParser() |
| 99 |
opts, pargs = getopt.getopt(sys.argv[1:], 'hsv', ['help', 'simulate', 'verbose']) |
91 |
parser.add_argument('--simulate', '-s', action='store_true', help='simulate update and just show actions') |
| 100 |
except: |
92 |
parser.add_argument('--verbose', '-v', action='store_true', help='print verbose information') |
| 101 |
usage(sys.stderr) |
93 |
args = parser.parse_args() |
| 102 |
sys.exit(2) |
94 |
|
| 103 |
|
95 |
if args.verbose: |
| 104 |
# get command line data |
|
|
| 105 |
for option, value in opts: |
| 106 |
if option == '-h' or option == '--help': |
| 107 |
usage() |
| 108 |
sys.exit(0) |
| 109 |
elif option == '-s' or option == '--simulate': |
| 110 |
global simulate |
| 111 |
simulate = True |
| 112 |
elif option == '-v' or option == '--verbose': |
| 113 |
global verbose |
96 |
global verbose |
| 114 |
verbose = True |
97 |
verbose = True |
| 115 |
|
98 |
|
| 116 |
hostdn = configRegistry.get('ldap/hostdn') |
99 |
hostdn = configRegistry.get('ldap/hostdn') |
| 117 |
if not hostdn: |
100 |
if not hostdn: |
| 118 |
print >>sys.stderr, "Error: ldap/hostdn is not set." |
101 |
print("Error: ldap/hostdn is not set.", file=sys.stderr) |
| 119 |
exit(1) |
102 |
exit(1) |
| 120 |
debug("Hostdn is %s\n" % hostdn) |
103 |
debug("Hostdn is %s\n" % hostdn) |
| 121 |
|
104 |
|
|
Lines 129-164
def main():
Link Here
|
| 129 |
sources = set() |
112 |
sources = set() |
| 130 |
mount_points = set() |
113 |
mount_points = set() |
| 131 |
try: |
114 |
try: |
| 132 |
f_old = open('/etc/fstab', 'r') |
115 |
with open('/etc/fstab', 'r') as f_old: |
| 133 |
if simulate: |
116 |
if args.simulate: |
| 134 |
# f_new = os.fdopen(os.dup(sys.stderr.fileno()), "w") |
117 |
# f_new = os.fdopen(os.dup(sys.stderr.fileno()), "w") |
| 135 |
from StringIO import StringIO |
118 |
f_new = StringIO() |
| 136 |
f_new = StringIO() |
|
|
| 137 |
else: |
| 138 |
f_new = open(fstabNew, 'w') |
| 139 |
for line in f_old: |
| 140 |
if MAGIC_LDAP not in line: |
| 141 |
f_new.write(line) |
| 142 |
debug("= %s" % line) |
| 143 |
else: |
119 |
else: |
| 144 |
debug("- %s" % line) |
120 |
f_new = open(fstabNew, 'w') |
| 145 |
if line.startswith('#'): |
121 |
|
| 146 |
continue |
122 |
for line in f_old: |
| 147 |
|
123 |
if MAGIC_LDAP not in line: |
| 148 |
line = line.rstrip('\n') |
124 |
f_new.write(line) |
| 149 |
fields = line.split(' ') # source_spec mount_point fs options freq passno |
125 |
debug("= %s" % line) |
| 150 |
|
126 |
else: |
| 151 |
sp = fields[0] |
127 |
debug("- %s" % line) |
| 152 |
sources.add(sp) |
128 |
|
| 153 |
|
129 |
if line.startswith('#'): |
| 154 |
try: |
130 |
continue |
| 155 |
mp = fields[1] |
131 |
|
| 156 |
if not mp.startswith('#'): |
132 |
line = line.rstrip('\n') |
| 157 |
mount_points.add(mp) |
133 |
fields = line.split(' ') # source_spec mount_point fs options freq passno |
| 158 |
except IndexError: |
134 |
|
| 159 |
pass |
135 |
sp = fields[0] |
| 160 |
|
136 |
sources.add(sp) |
| 161 |
f_old.close() |
137 |
|
|
|
138 |
try: |
| 139 |
mp = fields[1] |
| 140 |
if not mp.startswith('#'): |
| 141 |
mount_points.add(mp) |
| 142 |
except IndexError: |
| 143 |
pass |
| 162 |
except IOError as e: |
144 |
except IOError as e: |
| 163 |
exit(1, e) |
145 |
exit(1, e) |
| 164 |
|
146 |
|
|
Lines 189-205
def main():
Link Here
|
| 189 |
debug('not found, skipping\n') |
171 |
debug('not found, skipping\n') |
| 190 |
continue |
172 |
continue |
| 191 |
|
173 |
|
| 192 |
# skip share if from self |
|
|
| 193 |
if share_host == fqdn: |
| 194 |
debug('is self, skipping\n') |
| 195 |
continue |
| 196 |
|
| 197 |
mp = fields[-1] or share_path |
174 |
mp = fields[-1] or share_path |
| 198 |
# skip share if target already in fstab |
175 |
# skip share if target already in fstab |
| 199 |
if mp in mount_points: |
176 |
if mp in mount_points: |
| 200 |
debug('already mounted on %s, skipping\n' % mp) |
177 |
debug('already mounted on %s, skipping\n' % mp) |
| 201 |
continue |
178 |
continue |
| 202 |
|
179 |
|
|
|
180 |
# skip share if from self |
| 181 |
if share_host == fqdn and share_path == mp: |
| 182 |
debug('is self, skipping\n') |
| 183 |
continue |
| 184 |
|
| 203 |
nfs_path_fqdn = "%s:%s" % (share_host, share_path) |
185 |
nfs_path_fqdn = "%s:%s" % (share_host, share_path) |
| 204 |
# skip share if the source is already in the fstab |
186 |
# skip share if the source is already in the fstab |
| 205 |
if nfs_path_fqdn in sources: |
187 |
if nfs_path_fqdn in sources: |
|
Lines 227-248
def main():
Link Here
|
| 227 |
|
209 |
|
| 228 |
f_new.close() |
210 |
f_new.close() |
| 229 |
debug('Switching /etc/fstab...\n') |
211 |
debug('Switching /etc/fstab...\n') |
| 230 |
if not simulate: |
212 |
if not args.simulate: |
| 231 |
if os.path.isfile(fstabNew) and os.path.getsize(fstabNew) > 0: |
213 |
if os.path.isfile(fstabNew) and os.path.getsize(fstabNew) > 0: |
| 232 |
os.rename(fstabNew, '/etc/fstab') |
214 |
os.rename(fstabNew, '/etc/fstab') |
| 233 |
|
215 |
|
| 234 |
fp = open('/etc/mtab', 'r') |
216 |
with open('/etc/mtab', 'r') as fp: |
| 235 |
for line in fp: |
217 |
for line in fp: |
| 236 |
line = line.rstrip('\n') |
218 |
line = line.rstrip('\n') |
| 237 |
fields = line.split(' ') # source_spec mount_point fs options freq passno |
219 |
fields = line.split(' ') # source_spec mount_point fs options freq passno |
| 238 |
to_mount.discard(fields[1]) |
220 |
to_mount.discard(fields[1]) |
| 239 |
|
221 |
|
| 240 |
for mp in sorted(to_mount): |
222 |
for mp in sorted(to_mount): |
| 241 |
if not os.path.exists(mp): |
223 |
if not os.path.exists(mp): |
| 242 |
os.makedirs(mp) |
224 |
os.makedirs(mp) |
| 243 |
debug('Mounting %s...\n' % mp) |
225 |
debug('Mounting %s...\n' % mp) |
| 244 |
if not simulate: |
226 |
if not args.simulate: |
| 245 |
p = subprocess.Popen(['mount', mp]) |
227 |
subprocess.Popen(['mount', mp]) |
| 246 |
|
228 |
|
| 247 |
|
229 |
|
| 248 |
if __name__ == '__main__': |
230 |
if __name__ == '__main__': |