|
|
c88dcf |
#!/usr/bin/env python3
|
|
|
c88dcf |
"""
|
|
|
c88dcf |
Read in the deprecated /etc/sysconfig/nfs file and
|
|
|
c88dcf |
set the corresponding values in nfs.conf
|
|
|
c88dcf |
"""
|
|
|
c88dcf |
|
|
|
c88dcf |
from __future__ import print_function
|
|
|
c88dcf |
import os
|
|
|
c88dcf |
import sys
|
|
|
c88dcf |
import getopt
|
|
|
c88dcf |
import subprocess
|
|
|
c88dcf |
import configparser
|
|
|
c88dcf |
|
|
|
c88dcf |
CONF_NFS = '/etc/nfs.conf'
|
|
|
c88dcf |
CONF_IDMAP = '/etc/idmapd.conf'
|
|
|
c88dcf |
SYSCONF_NFS = '/etc/sysconfig/nfs'
|
|
|
c88dcf |
SYSCONF_BACKUP = ".rpmsave"
|
|
|
c88dcf |
CONF_TOOL = '/usr/sbin/nfsconf'
|
|
|
c88dcf |
|
|
|
c88dcf |
# options for nfsd found in RPCNFSDARGS
|
|
|
c88dcf |
OPTS_NFSD = 'dH:p:rR:N:V:stTuUG:L:'
|
|
|
c88dcf |
LONG_NFSD = ['debug', 'host=', 'port=', 'rdma=', 'nfs-version=', 'no-nfs-version=',
|
|
|
c88dcf |
'tcp', 'no-tcp', 'udp', 'no-udp', 'grace-time=', 'lease-time=']
|
|
|
c88dcf |
CONV_NFSD = {'-d': (CONF_NFS, 'nfsd', 'debug', 'all'),
|
|
|
c88dcf |
'-H': (CONF_NFS, 'nfsd', 'host', ','),
|
|
|
c88dcf |
'-p': (CONF_NFS, 'nfsd', 'port', '$1'),
|
|
|
c88dcf |
'-r': (CONF_NFS, 'nfsd', 'rdma', 'nfsrdma'),
|
|
|
c88dcf |
'-R': (CONF_NFS, 'nfsd', 'rdma', '$1'),
|
|
|
c88dcf |
'-N': (CONF_NFS, 'nfsd', 'vers$1', 'n'),
|
|
|
c88dcf |
'-V': (CONF_NFS, 'nfsd', 'vers$1', 'y'),
|
|
|
c88dcf |
'-t': (CONF_NFS, 'nfsd', 'tcp', '1'),
|
|
|
c88dcf |
'-T': (CONF_NFS, 'nfsd', 'tcp', '0'),
|
|
|
c88dcf |
'-u': (CONF_NFS, 'nfsd', 'udp', '1'),
|
|
|
c88dcf |
'-U': (CONF_NFS, 'nfsd', 'udp', '0'),
|
|
|
c88dcf |
'-G': (CONF_NFS, 'nfsd', 'grace-time', '$1'),
|
|
|
c88dcf |
'-L': (CONF_NFS, 'nfsd', 'lease-time', '$1'),
|
|
|
c88dcf |
'$1': (CONF_NFS, 'nfsd', 'threads', '$1'),
|
|
|
c88dcf |
'--debug': (CONF_NFS, 'nfsd', 'debug', 'all'),
|
|
|
c88dcf |
'--host': (CONF_NFS, 'nfsd', 'host', ','),
|
|
|
c88dcf |
'--port': (CONF_NFS, 'nfsd', 'port', '$1'),
|
|
|
c88dcf |
'--rdma': (CONF_NFS, 'nfsd', 'rdma', '$1'),
|
|
|
c88dcf |
'--no-nfs-version': (CONF_NFS, 'nfsd', 'vers$1', 'n'),
|
|
|
c88dcf |
'--nfs-version': (CONF_NFS, 'nfsd', 'vers$1', 'y'),
|
|
|
c88dcf |
'--tcp': (CONF_NFS, 'nfsd', 'tcp', '1'),
|
|
|
c88dcf |
'--no-tcp': (CONF_NFS, 'nfsd', 'tcp', '0'),
|
|
|
c88dcf |
'--udp': (CONF_NFS, 'nfsd', 'udp', '1'),
|
|
|
c88dcf |
'--no-udp': (CONF_NFS, 'nfsd', 'udp', '0'),
|
|
|
c88dcf |
'--grace-time': (CONF_NFS, 'nfsd', 'grace-time', '$1'),
|
|
|
c88dcf |
'--lease-time': (CONF_NFS, 'nfsd', 'lease-time', '$1'),
|
|
|
c88dcf |
}
|
|
|
c88dcf |
|
|
|
c88dcf |
# options for mountd found in RPCMOUNTDOPTS
|
|
|
c88dcf |
OPTS_MOUNTD = 'go:d:H:p:N:nrs:t:V:'
|
|
|
c88dcf |
LONG_MOUNTD = ['descriptors=', 'debug=', 'nfs-version=', 'no-nfs-version=',
|
|
|
c88dcf |
'port=', 'no-tcp', 'ha-callout=', 'state-directory-path=',
|
|
|
c88dcf |
'num-threads=', 'reverse-lookup', 'manage-gids', 'no-udp']
|
|
|
c88dcf |
|
|
|
c88dcf |
CONV_MOUNTD = {'-g': (CONF_NFS, 'mountd', 'manage-gids', '1'),
|
|
|
c88dcf |
'-o': (CONF_NFS, 'mountd', 'descriptors', '$1'),
|
|
|
c88dcf |
'-d': (CONF_NFS, 'mountd', 'debug', '$1'),
|
|
|
c88dcf |
'-H': (CONF_NFS, 'mountd', 'ha-callout', '$1'),
|
|
|
c88dcf |
'-p': (CONF_NFS, 'mountd', 'port', '$1'),
|
|
|
c88dcf |
'-N': (CONF_NFS, 'nfsd', 'vers$1', 'n'),
|
|
|
c88dcf |
'-V': (CONF_NFS, 'nfsd', 'vers$1', 'y'),
|
|
|
c88dcf |
'-n': (CONF_NFS, 'nfsd', 'tcp', '0'),
|
|
|
c88dcf |
'-s': (CONF_NFS, 'mountd', 'stat-directory-path', '$1'),
|
|
|
c88dcf |
'-t': (CONF_NFS, 'mountd', 'threads', '$1'),
|
|
|
c88dcf |
'-r': (CONF_NFS, 'mountd', 'reverse-lookup', '1'),
|
|
|
c88dcf |
'-u': (CONF_NFS, 'nfsd', 'udp', '0'),
|
|
|
c88dcf |
'--manage-gids': (CONF_NFS, 'mountd', 'manage-gids', '1'),
|
|
|
c88dcf |
'--descriptors': (CONF_NFS, 'mountd', 'descriptors', '$1'),
|
|
|
c88dcf |
'--debug': (CONF_NFS, 'mountd', 'debug', '$1'),
|
|
|
c88dcf |
'--ha-callout': (CONF_NFS, 'mountd', 'ha-callout', '$1'),
|
|
|
c88dcf |
'--port': (CONF_NFS, 'mountd', 'port', '$1'),
|
|
|
c88dcf |
'--nfs-version': (CONF_NFS, 'nfsd', 'vers$1', 'y'),
|
|
|
c88dcf |
'--no-nfs-version': (CONF_NFS, 'nfsd', 'vers$1', 'n'),
|
|
|
c88dcf |
'--no-tcp': (CONF_NFS, 'nfsd', 'tcp', '0'),
|
|
|
c88dcf |
'--state-directory-path': (CONF_NFS, 'mountd', 'state-directory-path', '$1'),
|
|
|
c88dcf |
'--num-threads': (CONF_NFS, 'mountd', 'threads', '$1'),
|
|
|
c88dcf |
'--reverse-lookup': (CONF_NFS, 'mountd', 'reverse-lookup', '1'),
|
|
|
c88dcf |
'--no-udp': (CONF_NFS, 'nfsd', 'udp', '0'),
|
|
|
c88dcf |
}
|
|
|
c88dcf |
|
|
|
c88dcf |
# options for statd found in STATDARG
|
|
|
c88dcf |
OPTS_STATD = 'o:p:T:U:n:P:H:L'
|
|
|
c88dcf |
LONG_STATD = ['outgoing-port=', 'port=', 'name=', 'state-directory-path=',
|
|
|
c88dcf |
'ha-callout=', 'nlm-port=', 'nlm-udp-port=', 'no-notify']
|
|
|
c88dcf |
CONV_STATD = {'-o': (CONF_NFS, 'statd', 'outgoing-port', '$1'),
|
|
|
c88dcf |
'-p': (CONF_NFS, 'statd', 'port', '$1'),
|
|
|
c88dcf |
'-T': (CONF_NFS, 'lockd', 'port', '$1'),
|
|
|
c88dcf |
'-U': (CONF_NFS, 'lockd', 'udp-port', '$1'),
|
|
|
c88dcf |
'-n': (CONF_NFS, 'statd', 'name', '$1'),
|
|
|
c88dcf |
'-P': (CONF_NFS, 'statd', 'state-directory-path', '$1'),
|
|
|
c88dcf |
'-H': (CONF_NFS, 'statd', 'ha-callout', '$1'),
|
|
|
c88dcf |
'-L': (CONF_NFS, 'statd', 'no-notify', '1'),
|
|
|
c88dcf |
'--outgoing-port': (CONF_NFS, 'statd', 'outgoing-port', '$1'),
|
|
|
c88dcf |
'--port': (CONF_NFS, 'statd', 'port', '$1'),
|
|
|
c88dcf |
'--name': (CONF_NFS, 'statd', 'name', '$1'),
|
|
|
c88dcf |
'--state-directory-path': (CONF_NFS, 'statd', 'state-directory-path', '$1'),
|
|
|
c88dcf |
'--ha-callout': (CONF_NFS, 'statd', 'ha-callout', '$1'),
|
|
|
c88dcf |
'--nlm-port': (CONF_NFS, 'lockd', 'port', '$1'),
|
|
|
c88dcf |
'--nlm-udp-port': (CONF_NFS, 'lockd', 'udp-port', '$1'),
|
|
|
c88dcf |
'--no-notify': (CONF_NFS, 'statd', 'no-notify', '1'),
|
|
|
c88dcf |
}
|
|
|
c88dcf |
|
|
|
c88dcf |
# options for sm-notify found in SMNOTIFYARGS
|
|
|
d4362b |
OPTS_SMNOTIFY = 'dm:np:v:P:f'
|
|
|
c88dcf |
CONV_SMNOTIFY = {'-d': (CONF_NFS, 'sm-notify', 'debug', 'all'),
|
|
|
c88dcf |
'-m': (CONF_NFS, 'sm-notify', 'retry-time', '$1'),
|
|
|
c88dcf |
'-n': (CONF_NFS, 'sm-notify', 'update-state', '1'),
|
|
|
c88dcf |
'-p': (CONF_NFS, 'sm-notify', 'outgoing-port', '$1'),
|
|
|
c88dcf |
'-v': (CONF_NFS, 'sm-notify', 'outgoing-addr', '$1'),
|
|
|
d4362b |
'-f': (CONF_NFS, 'sm-notify', 'force', '1'),
|
|
|
c88dcf |
'-P': (CONF_NFS, 'statd', 'state-directory-path', '$1'),
|
|
|
c88dcf |
}
|
|
|
c88dcf |
|
|
|
c88dcf |
# options for idmapd found in RPCIDMAPDARGS
|
|
|
c88dcf |
OPTS_IDMAPD = 'vp:CS'
|
|
|
c88dcf |
CONV_IDMAPD = {'-v': (CONF_IDMAP, 'general', 'verbosity', '+'),
|
|
|
c88dcf |
'-p': (CONF_NFS, 'general', 'pipefs-directory', '$1'),
|
|
|
c88dcf |
'-C': (CONF_IDMAP, 'general', 'client-only', '1'),
|
|
|
c88dcf |
'-S': (CONF_IDMAP, 'general', 'server-only', '1'),
|
|
|
c88dcf |
}
|
|
|
c88dcf |
|
|
|
c88dcf |
# options for gssd found in RPCGSSDARGS
|
|
|
c88dcf |
OPTS_GSSD = 'Mnvrp:k:d:t:T:R:lD'
|
|
|
c88dcf |
CONV_GSSD = {'-M': (CONF_NFS, 'gssd', 'use-memcache', '1'),
|
|
|
c88dcf |
'-n': (CONF_NFS, 'gssd', 'root_uses_machine_creds', '0'),
|
|
|
c88dcf |
'-v': (CONF_NFS, 'gssd', 'verbosity', '+'),
|
|
|
c88dcf |
'-r': (CONF_NFS, 'gssd', 'rpc-verbosity', '+'),
|
|
|
c88dcf |
'-p': (CONF_NFS, 'general', 'pipefs-directory', '$1'),
|
|
|
c88dcf |
'-k': (CONF_NFS, 'gssd', 'keytab-file', '$1'),
|
|
|
c88dcf |
'-d': (CONF_NFS, 'gssd', 'cred-cache-directory', '$1'),
|
|
|
c88dcf |
'-t': (CONF_NFS, 'gssd', 'context-timeout', '$1'),
|
|
|
c88dcf |
'-T': (CONF_NFS, 'gssd', 'rpc-timeout', '$1'),
|
|
|
c88dcf |
'-R': (CONF_NFS, 'gssd', 'preferred-realm', '$1'),
|
|
|
c88dcf |
'-l': (CONF_NFS, 'gssd', 'limit-to-legacy-enctypes', '0'),
|
|
|
c88dcf |
'-D': (CONF_NFS, 'gssd', 'avoid-dns', '0'),
|
|
|
c88dcf |
}
|
|
|
c88dcf |
|
|
|
c88dcf |
# options for blkmapd found in BLKMAPDARGS
|
|
|
c88dcf |
OPTS_BLKMAPD = ''
|
|
|
c88dcf |
CONV_BLKMAPD = {}
|
|
|
c88dcf |
|
|
|
c88dcf |
# meta list of all the getopt lists
|
|
|
c88dcf |
GETOPT_MAPS = [('RPCNFSDARGS', OPTS_NFSD, LONG_NFSD, CONV_NFSD),
|
|
|
c88dcf |
('RPCMOUNTDOPTS', OPTS_MOUNTD, LONG_MOUNTD, CONV_MOUNTD),
|
|
|
c88dcf |
('STATDARG', OPTS_STATD, LONG_STATD, CONV_STATD),
|
|
|
c88dcf |
('STATDARGS', OPTS_STATD, LONG_STATD, CONV_STATD),
|
|
|
c88dcf |
('SMNOTIFYARGS', OPTS_SMNOTIFY, [], CONV_SMNOTIFY),
|
|
|
c88dcf |
('RPCIDMAPDARGS', OPTS_IDMAPD, [], CONV_IDMAPD),
|
|
|
c88dcf |
('RPCGSSDARGS', OPTS_GSSD, [], CONV_GSSD),
|
|
|
c88dcf |
('BLKMAPDARGS', OPTS_BLKMAPD, [], CONV_BLKMAPD),
|
|
|
c88dcf |
]
|
|
|
c88dcf |
|
|
|
d4362b |
# any fixups we need to apply first
|
|
|
d4362b |
GETOPT_FIXUP = {'RPCNFSDARGS': ('--rdma', '--rdma=nfsrdma'),
|
|
|
d4362b |
}
|
|
|
d4362b |
|
|
|
c88dcf |
# map for all of the single option values
|
|
|
c88dcf |
VALUE_MAPS = {'LOCKD_TCPPORT': (CONF_NFS, 'lockd', 'port', '$1'),
|
|
|
c88dcf |
'LOCKD_UDPPORT': (CONF_NFS, 'lockd', 'udp-port', '$1'),
|
|
|
c88dcf |
'RPCNFSDCOUNT': (CONF_NFS, 'nfsd', 'threads', '$1'),
|
|
|
c88dcf |
'NFSD_V4_GRACE': (CONF_NFS, 'nfsd', 'grace-time', '$1'),
|
|
|
c88dcf |
'NFSD_V4_LEASE': (CONF_NFS, 'nfsd', 'lease-time', '$1'),
|
|
|
c88dcf |
'MOUNTD_PORT': (CONF_NFS, 'mountd', 'port', '$1'),
|
|
|
c88dcf |
'STATD_PORT': (CONF_NFS, 'statd', 'port', '$1'),
|
|
|
c88dcf |
'STATD_OUTGOING_PORT': (CONF_NFS, 'statd', 'outgoing-port', '$1'),
|
|
|
c88dcf |
'STATD_HA_CALLOUT': (CONF_NFS, 'statd', 'ha-callout', '$1'),
|
|
|
c88dcf |
'GSS_USE_PROXY': (CONF_NFS, 'gssd', 'use-gss-proxy', '$1')
|
|
|
c88dcf |
}
|
|
|
c88dcf |
|
|
|
c88dcf |
def eprint(*args, **kwargs):
|
|
|
c88dcf |
""" Print error to stderr """
|
|
|
c88dcf |
print(*args, file=sys.stderr, **kwargs)
|
|
|
c88dcf |
|
|
|
c88dcf |
def makesub(param, value):
|
|
|
c88dcf |
""" Variable substitution """
|
|
|
c88dcf |
return param.replace('$1', value)
|
|
|
c88dcf |
|
|
|
c88dcf |
def set_value(value, entry):
|
|
|
c88dcf |
""" Set a configuration value by running nfsconf tool"""
|
|
|
c88dcf |
cfile, section, tag, param = entry
|
|
|
c88dcf |
|
|
|
c88dcf |
tag = makesub(tag, value)
|
|
|
c88dcf |
param = makesub(param, value)
|
|
|
c88dcf |
if param == '+':
|
|
|
c88dcf |
param = value
|
|
|
c88dcf |
if param == ',':
|
|
|
c88dcf |
param = value
|
|
|
c88dcf |
args = [CONF_TOOL, "--file", cfile, "--set", section, tag, param]
|
|
|
c88dcf |
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
subprocess.check_output(args, stderr=subprocess.STDOUT)
|
|
|
c88dcf |
except subprocess.CalledProcessError as e:
|
|
|
c88dcf |
print("Error running nfs-conf tool:\n %s" % (e.output.decode()))
|
|
|
c88dcf |
print("Args: %s\n" % args)
|
|
|
c88dcf |
raise Exception
|
|
|
c88dcf |
|
|
|
c88dcf |
def convert_getopt(optname, options, optstring, longopts, conversions):
|
|
|
c88dcf |
""" Parse option string into seperate config items
|
|
|
c88dcf |
|
|
|
c88dcf |
Take a getopt string and a table of conversions
|
|
|
c88dcf |
parse it all and spit out the converted config
|
|
|
c88dcf |
|
|
|
c88dcf |
Keyword arguments:
|
|
|
c88dcf |
options -- the argv string to convert
|
|
|
c88dcf |
optstring -- getopt format option list
|
|
|
c88dcf |
conversions -- table of translations
|
|
|
c88dcf |
"""
|
|
|
c88dcf |
optcount = 0
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
args = options.strip('\"').split()
|
|
|
d4362b |
if optname in GETOPT_FIXUP:
|
|
|
d4362b |
(k, v) = GETOPT_FIXUP[optname]
|
|
|
d4362b |
for i, opt in enumerate(args):
|
|
|
d4362b |
if opt == k:
|
|
|
d4362b |
args[i] = v
|
|
|
d4362b |
elif opt == '--':
|
|
|
d4362b |
break
|
|
|
c88dcf |
optlist, optargs = getopt.gnu_getopt(args, optstring, longopts=longopts)
|
|
|
c88dcf |
except getopt.GetoptError as err:
|
|
|
c88dcf |
eprint(err)
|
|
|
c88dcf |
raise Exception
|
|
|
c88dcf |
|
|
|
c88dcf |
setlist = {}
|
|
|
c88dcf |
for (k, v) in optlist:
|
|
|
c88dcf |
if k in conversions:
|
|
|
c88dcf |
# it's already been set once
|
|
|
c88dcf |
param = conversions[k][3]
|
|
|
c88dcf |
tag = k + makesub(conversions[k][2], v)
|
|
|
c88dcf |
if tag in setlist:
|
|
|
c88dcf |
value = setlist[tag][0]
|
|
|
c88dcf |
# is it a cummulative entry
|
|
|
c88dcf |
if param == '+':
|
|
|
c88dcf |
value = str(int(value) + 1)
|
|
|
c88dcf |
if param == ',':
|
|
|
c88dcf |
value += "," + v
|
|
|
c88dcf |
else:
|
|
|
c88dcf |
if param == '+':
|
|
|
c88dcf |
value = "1"
|
|
|
c88dcf |
elif param == ',':
|
|
|
c88dcf |
value = v
|
|
|
c88dcf |
else:
|
|
|
c88dcf |
value = v
|
|
|
c88dcf |
setlist[tag] = (value, conversions[k])
|
|
|
c88dcf |
else:
|
|
|
c88dcf |
if v:
|
|
|
c88dcf |
eprint("Ignoring unrecognised option %s=%s in %s" % (k, v, optname))
|
|
|
c88dcf |
else:
|
|
|
c88dcf |
eprint("Ignoring unrecognised option %s in %s" % (k, optname))
|
|
|
c88dcf |
|
|
|
c88dcf |
|
|
|
c88dcf |
for v, c in setlist.values():
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
set_value(v, c)
|
|
|
c88dcf |
optcount += 1
|
|
|
c88dcf |
except Exception:
|
|
|
c88dcf |
raise
|
|
|
c88dcf |
|
|
|
c88dcf |
i = 1
|
|
|
c88dcf |
for o in optargs:
|
|
|
c88dcf |
opname = '$' + str(i)
|
|
|
c88dcf |
if opname in conversions:
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
set_value(o, conversions[opname])
|
|
|
c88dcf |
optcount += 1
|
|
|
c88dcf |
except Exception:
|
|
|
c88dcf |
raise
|
|
|
c88dcf |
else:
|
|
|
c88dcf |
eprint("Unrecognised trailing arguments")
|
|
|
c88dcf |
raise Exception
|
|
|
c88dcf |
i += 1
|
|
|
c88dcf |
|
|
|
c88dcf |
return optcount
|
|
|
c88dcf |
|
|
|
c88dcf |
def map_values():
|
|
|
c88dcf |
""" Main function """
|
|
|
c88dcf |
mapcount = 0
|
|
|
c88dcf |
|
|
|
c88dcf |
# Lets load the old config
|
|
|
c88dcf |
with open(SYSCONF_NFS) as cfile:
|
|
|
c88dcf |
file_content = '[sysconf]\n' + cfile.read()
|
|
|
c88dcf |
sysconfig = configparser.RawConfigParser()
|
|
|
c88dcf |
sysconfig.read_string(file_content)
|
|
|
c88dcf |
|
|
|
c88dcf |
# Map all the getopt option lists
|
|
|
c88dcf |
for (name, opts, lopts, conv) in GETOPT_MAPS:
|
|
|
c88dcf |
if name in sysconfig['sysconf']:
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
mapcount += convert_getopt(name, sysconfig['sysconf'][name], opts,
|
|
|
c88dcf |
lopts, conv)
|
|
|
c88dcf |
except Exception:
|
|
|
c88dcf |
eprint("Error whilst converting %s to nfsconf options." % (name))
|
|
|
c88dcf |
raise
|
|
|
c88dcf |
|
|
|
c88dcf |
# Map the single value options
|
|
|
c88dcf |
for name, opts in VALUE_MAPS.items():
|
|
|
c88dcf |
if name in sysconfig['sysconf']:
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
value = sysconfig['sysconf'][name]
|
|
|
c88dcf |
set_value(value.strip('\"'), opts)
|
|
|
c88dcf |
mapcount += 1
|
|
|
c88dcf |
except Exception:
|
|
|
c88dcf |
raise
|
|
|
c88dcf |
|
|
|
c88dcf |
# All went well, move aside the old file
|
|
|
c88dcf |
# but dont bother if there were no changes and
|
|
|
c88dcf |
# an old config file already exists
|
|
|
c88dcf |
backupfile = SYSCONF_NFS + SYSCONF_BACKUP
|
|
|
c88dcf |
if mapcount > 0 or not os.path.exists(backupfile):
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
os.replace(SYSCONF_NFS, backupfile)
|
|
|
c88dcf |
except OSError as err:
|
|
|
c88dcf |
eprint("Error moving old config %s: %s" % (SYSCONF_NFS, err))
|
|
|
c88dcf |
raise
|
|
|
c88dcf |
|
|
|
c88dcf |
# Main routine
|
|
|
c88dcf |
try:
|
|
|
c88dcf |
map_values()
|
|
|
c88dcf |
except Exception as e:
|
|
|
c88dcf |
eprint(e)
|
|
|
c88dcf |
eprint("Conversion failed. Please correct the error and try again.")
|
|
|
c88dcf |
exit(1)
|