From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 7 Aug 2007 20:22:55 -0000 Subject: [Cluster-devel] conga/luci/utils luci_admin Message-ID: <20070807202255.20736.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: conga Changes by: rmccabe at sourceware.org 2007-08-07 20:22:54 Modified files: luci/utils : luci_admin Log message: Big cleanup. Detect and report more error conditions. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/utils/luci_admin.diff?cvsroot=cluster&r1=1.53&r2=1.54 --- conga/luci/utils/luci_admin 2007/02/05 20:08:28 1.53 +++ conga/luci/utils/luci_admin 2007/08/07 20:22:54 1.54 @@ -1,118 +1,116 @@ #!/usr/bin/python # Copyright (C) 2006-2007 Red Hat, Inc. +# +# This program is free software; you can redistribute +# it and/or modify it under the terms of version 2 of the +# GNU General Public License as published by the +# Free Software Foundation. -import sys, os, stat, select, string, pwd -from sys import stderr, argv +import sys, os, select, pwd +from stat import S_ISREG import types import xml import xml.dom -from xml.dom import minidom - + sys.path.extend(( '/usr/lib/luci/zope/lib/python', '/usr/lib/luci/zope/lib/python/Products', + '/usr/lib/zope/lib/python', + '/usr/lib/zope/lib/python/Products' '/usr/lib64/luci/zope/lib/python', '/usr/lib64/luci/zope/lib/python/Products', '/usr/lib64/luci/zope/lib64/python', '/usr/lib64/luci/zope/lib64/python/Products', '/usr/lib64/zope/lib64/python', '/usr/lib64/zope/lib/python', - '/usr/lib/zope/lib/python', '/usr/lib64/zope/lib/python/Products', '/usr/lib64/zope/lib64/python/Products', - '/usr/lib/zope/lib/python/Products' )) from Products import __path__ -for i in ['/usr/lib/luci/zope/lib/python/Products', - '/usr/lib64/luci/zope/lib/python/Products', - '/usr/lib64/luci/zope/lib64/python/Products', - '/usr/lib64/zope/lib/python/Products', - '/usr/lib64/zope/lib64/python/Products', - '/usr/lib/zope/lib/python/Products']: - if os.path.isdir(i): - __path__.append(i) - -LUCI_INIT_DEBUG = 0 - -LUCI_USER = 'luci' -LUCI_GROUP = 'luci' - -LUCI_HOME_DIR = '/var/lib/luci' -LUCI_DB_PATH = LUCI_HOME_DIR + '/var/Data.fs' -LUCI_CERT_DIR = LUCI_HOME_DIR + '/var/certs/' -LUCI_PEERS_DIR = LUCI_CERT_DIR + 'peers/' -LUCI_BACKUP_DIR = LUCI_HOME_DIR + '/var' -LUCI_BACKUP_PATH = LUCI_BACKUP_DIR + '/luci_backup.xml' -LUCI_ADMIN_SET_PATH = LUCI_HOME_DIR + '/.default_password_has_been_reset' - -SSL_PRIVKEY_NAME = 'privkey.pem' -SSL_PUBKEY_NAME = 'cacert.pem' -SSL_HTTPS_PRIVKEY_NAME = 'https.key.pem' -SSL_HTTPS_PUBKEY_NAME = 'https.pem' -SSL_KEYCONFIG_NAME = 'cacert.config' - -SSL_PRIVKEY_PATH = LUCI_CERT_DIR + SSL_PRIVKEY_NAME -SSL_PUBKEY_PATH = LUCI_CERT_DIR + SSL_PUBKEY_NAME -SSL_HTTPS_PRIVKEY_PATH = LUCI_CERT_DIR + SSL_HTTPS_PRIVKEY_NAME -SSL_HTTPS_PUBKEY_PATH = LUCI_CERT_DIR + SSL_HTTPS_PUBKEY_NAME -SSL_KEYCONFIG_PATH = LUCI_CERT_DIR + SSL_KEYCONFIG_NAME + +for tmppath in [ + '/usr/lib/luci/zope/lib/python/Products', + '/usr/lib64/luci/zope/lib/python/Products', + '/usr/lib64/luci/zope/lib64/python/Products', + '/usr/lib64/zope/lib/python/Products', + '/usr/lib64/zope/lib64/python/Products', + '/usr/lib/zope/lib/python/Products' +]: + if os.path.isdir(tmppath): + __path__.append(tmppath) + +LUCI_USER = 'luci' +LUCI_GROUP = 'luci' + +LUCI_HOME_DIR = '/var/lib/luci' +LUCI_DB_PATH = '%s/var/Data.fs' % LUCI_HOME_DIR +LUCI_CERT_DIR = '%s/var/certs/' % LUCI_HOME_DIR +LUCI_PEERS_DIR = '%speers/' % LUCI_CERT_DIR +LUCI_BACKUP_DIR = '%s/var' % LUCI_HOME_DIR +LUCI_BACKUP_PATH = '%s/luci_backup.xml' % LUCI_BACKUP_DIR +LUCI_ADMIN_SET_PATH = '%s/.default_password_has_been_reset' % LUCI_HOME_DIR + +SSL_PRIVKEY_NAME = 'privkey.pem' +SSL_PUBKEY_NAME = 'cacert.pem' +SSL_HTTPS_PRIVKEY_NAME = 'https.key.pem' +SSL_HTTPS_PUBKEY_NAME = 'https.pem' +SSL_KEYCONFIG_NAME = 'cacert.config' + +SSL_PRIVKEY_PATH = '%s%s' % (LUCI_CERT_DIR, SSL_PRIVKEY_NAME) +SSL_PUBKEY_PATH = '%s%s' % (LUCI_CERT_DIR, SSL_PUBKEY_NAME) +SSL_HTTPS_PRIVKEY_PATH = '%s%s' % (LUCI_CERT_DIR, SSL_HTTPS_PRIVKEY_NAME) +SSL_HTTPS_PUBKEY_PATH = '%s%s' % (LUCI_CERT_DIR, SSL_HTTPS_PUBKEY_NAME) +SSL_KEYCONFIG_PATH = '%s%s' % (LUCI_CERT_DIR, SSL_KEYCONFIG_NAME) ssl_key_data = [ - { 'id' : SSL_PRIVKEY_PATH, - 'name': SSL_PRIVKEY_NAME, - 'type': 'private', - 'mode': 0600 }, - { 'id' : SSL_HTTPS_PRIVKEY_PATH, - 'name': SSL_HTTPS_PRIVKEY_NAME, - 'type': 'private', - 'mode': 0600 }, - { 'id' : SSL_PUBKEY_PATH, - 'name': SSL_PUBKEY_NAME, - 'type': 'public', - 'mode': 0644 }, - { 'id' : SSL_HTTPS_PUBKEY_PATH, - 'name': SSL_HTTPS_PUBKEY_NAME, - 'type': 'public', - 'mode': 0644 }, - { 'id' : SSL_KEYCONFIG_PATH, - 'name': SSL_KEYCONFIG_NAME, - 'type': 'config', - 'mode': 0644 } + { 'id': SSL_PRIVKEY_PATH, + 'name': SSL_PRIVKEY_NAME, + 'type': 'private', + 'mode': 0600 }, + { 'id': SSL_HTTPS_PRIVKEY_PATH, + 'name': SSL_HTTPS_PRIVKEY_NAME, + 'type': 'private', + 'mode': 0600 }, + { 'id': SSL_PUBKEY_PATH, + 'name': SSL_PUBKEY_NAME, + 'type': 'public', + 'mode': 0644 }, + { 'id': SSL_HTTPS_PUBKEY_PATH, + 'name': SSL_HTTPS_PUBKEY_NAME, + 'type': 'public', + 'mode': 0644 }, + { 'id': SSL_KEYCONFIG_PATH, + 'name': SSL_KEYCONFIG_NAME, + 'type': 'config', + 'mode': 0644 } ] + for name in os.listdir(LUCI_PEERS_DIR): - path = LUCI_PEERS_DIR + name - if stat.S_ISREG(os.stat(path).st_mode): - ssl_key_data.append({'id' : path, - 'name' : path.lstrip(LUCI_CERT_DIR), - 'type' : 'public', - 'mode' : 0644}) + ssl_path = '%s%s' % (LUCI_PEERS_DIR, name) -#null = file(os.devnull, 'rwb+', 0) - available on python 2.4 and above!!! -null = file('/dev/null', 'rwb+', 0) -orig_stderr = sys.stderr + if S_ISREG(os.stat(ssl_path).st_mode): + ssl_key_data.append({ + 'id': ssl_path, + 'name': ssl_path.lstrip(LUCI_CERT_DIR), + 'type': 'public', + 'mode': 0644 + }) -if LUCI_INIT_DEBUG: +orig_stderr = sys.stderr +if '--debug' in sys.argv or '--verbose' in sys.argv: verbose = sys.stderr else: - verbose = null - - + verbose = file('/dev/null', 'rwb+', 0) def get_luci_uid_gid(): - try: - luci = pwd.getpwnam(LUCI_USER)[2:4] - if not luci: - raise - if len(luci) != 2: - raise - return luci - except: - msg = 'Cannot find the \"' + LUCI_USER + '\" user.\n' - sys.stderr.write(msg) - raise msg - + luci = pwd.getpwnam(LUCI_USER)[2:4] + if not luci: + raise Exception, 'user lookup failed' + if len(luci) != 2: + raise Exception, 'user lookup failed' + return luci def set_default_passwd_reset_flag(): # set flag marking admin password has been set @@ -123,64 +121,68 @@ return True def get_default_passwd_reset_flag(): - return open(LUCI_ADMIN_SET_PATH, 'r').read(16).strip() == 'True' - + try: + return open(LUCI_ADMIN_SET_PATH, 'r').read(16).strip() == 'True' + except Exception, e: + verbose.write('Failed to write to "%s": %s\n' \ + % (LUCI_ADMIN_SET_PATH, str(e))) + return False def read_passwd(prompt, confirm_prompt): from getpass import getpass + while True: s1 = getpass(prompt) if len(s1) < 6: - print 'Password has to be at least 6 characters long' + sys.stderr.write('Passwords must be at least 6 characters long.\n') continue - if ' ' in s1: - print 'Spaces are not allowed in passwords' + + if ' ' in s1 or '\t' in s1: + sys.stderr.write('Spaces are not allowed in passwords.\n') continue + s2 = getpass(confirm_prompt) if s1 != s2: - print 'Passwords mismatch, try again' + sys.stderr.write('Passwords don\'t match. Try again.\n') continue return s1 - - def restore_luci_db_fsattr(): uid, gid = -1, -1 try: uid, gid = get_luci_uid_gid() except: + sys.stderr.write('Unable to determine the user and group of the luci user "%s"\n' \ + % LUCI_USER) return -1 - + try: os.chown(LUCI_DB_PATH, uid, gid) os.chmod(LUCI_DB_PATH, 0600) - for i in [ '.tmp', '.old', '.index', '.lock' ]: + for ext in [ '.tmp', '.old', '.index', '.lock' ]: + cur_path = '%s%s' % (LUCI_DB_PATH, ext) try: - os.chown(LUCI_DB_PATH + i, uid, gid) - os.chmod(LUCI_DB_PATH + i, 0600) - except: pass - except: - sys.stderr.write('Unable to change ownership of the Luci database back to user \"' + LUCI_USER + '\"\n') + os.chown(cur_path, uid, gid) + os.chmod(cur_path, 0600) + except Exception, ei: + sys.stderr.write('Unable to change ownership of "%s" to user "%s": %s\n' \ + % (cur_path, LUCI_USER, str(ei))) + except Exception, e: + sys.stderr.write('Unable to change ownership of the Luci database "%s" back to user "%s": %s\n' \ + % (LUCI_DB_PATH, LUCI_USER, str(e))) return -1 def set_zope_passwd(user, passwd): - sys.stderr = null - import ZODB + sys.stderr = verbose from ZODB.FileStorage import FileStorage from ZODB.DB import DB - import OFS from OFS.Application import AppInitializer - import OFS.Folder import AccessControl import AccessControl.User from AccessControl.AuthEncoding import SSHADigestScheme from AccessControl.SecurityManagement import newSecurityManager import transaction - import Products.CMFCore - import Products.CMFCore.MemberDataTool import App.ImageFile - import Products.PluggableAuthService.plugins.ZODBUserManager - import BTrees.OOBTree # Zope wants to open a www/ok.gif and images/error.gif # when you initialize the application object. This keeps # the AppInitializer(app).initialize() call below from failing. @@ -193,43 +195,48 @@ conn = db.open() except IOError, e: if e[0] == 11: - sys.stderr.write('It appears that Luci is running. Please stop Luci before attempting to reset passwords.\n') + sys.stderr.write('It appears that the luci service is running. You must stop the luci service before using this tool to reset passwords.\n') return -1 else: - sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n') + sys.stderr.write('Unable to open the Luci database "%s": %s\n' \ + % (LUCI_DB_PATH, str(e))) return -1 except Exception, e: - sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n') + sys.stderr.write('Unable to open the Luci database "%s": %s\n' \ + % (LUCI_DB_PATH, str(e))) return -1 try: - sys.stderr = null + sys.stderr = verbose tempuser = AccessControl.User.UnrestrictedUser('admin', '', - ('manage','Manager', 'Owner', 'View', 'Authenticated'), []) + ('manage', 'Manager', 'Owner', 'View', 'Authenticated'), []) newSecurityManager(None, tempuser) app = conn.root()['Application'] AppInitializer(app).initialize() sys.stderr = orig_stderr - except: + except Exception, e: sys.stderr = orig_stderr - sys.stderr.write('An error occurred while setting the password for user \"' + user + '\"\n') + sys.stderr.write('An error occurred while setting the password for user "%s": %s\n' \ + % (user, str(e))) return -1 ret = -1 try: pwd_scheme = SSHADigestScheme - pwd_hash = '{SSHA}' + pwd_scheme.encrypt(SSHADigestScheme(), passwd) + pwd_hash = '{SSHA}%s' % pwd_scheme.encrypt(SSHADigestScheme(), passwd) acl_users = app.acl_users.users if len(acl_users): acl_users._user_passwords[user] = pwd_hash transaction.commit() ret = 0 else: - raise - except: - sys.stderr.write('Unable to set the password for user \"' + user + '\"\n') + raise Exception, 'failed to set password' + except Exception, e: + sys.stderr = orig_stderr + sys.stderr.write('Unable to set the password for user "%s": %s\n' \ + % (user, str(e))) conn.close() db.pack() @@ -238,34 +245,39 @@ if restore_luci_db_fsattr(): return -1 - + if user == 'admin' and ret == 0: set_default_passwd_reset_flag() - - return ret + return ret -def luci_restore_certs(certList): +def luci_restore_certs(path, certList): if not certList or len(certList) < 1: - sys.stderr.write('Your backup file contains no certificate data. Please check that your backup file is not corrupt.\n') + sys.stderr.write('Backup file "%s" contains no certificate data\n' \ + % path) + sys.stderr.write('Please check that your backup file is not corrupt.\n') return -1 certList = certList[0].getElementsByTagName('certificate') if not certList or len(certList) < 1: - sys.stderr.write('Your backup file contains no certificate data. Please check that your backup file is not corrupt.\n') + sys.stderr.write('Backup file "%s" contains no certificate data\n' \ + % path) + sys.stderr.write('Please check that your backup file is not corrupt.\n') return -1 - uid, gid = -1, -1 + try: uid, gid = get_luci_uid_gid() - except: + except Exception, e: + verbose.write('Error getting uid: %s' % str(e)) return -1 for c in certList: - path = c.getAttribute('name') - if not path: - sys.stderr.write('Missing \"name\" field for certificate.\n') + cert_path = c.getAttribute('name') + if not cert_path : + sys.stderr.write('Backup file "%s" is missing the "name" attribute for a certificate.\n' \ + % path) return -1 - path = LUCI_CERT_DIR + str(path) + cert_path = '%s%s' % (LUCI_CERT_DIR, str(cert_path)) mode = c.getAttribute('mode') if not mode: @@ -275,48 +287,50 @@ data = c.firstChild if not data or not data.wholeText: - sys.stderr.write('\"' + path + '\" has no certificate data.') + sys.stderr.write('Backup file "%s" contains no certificate data.\n' \ + % path) return -1 # Because .prettyprint() was called to write the backup.. data = data.wholeText.strip() if len(data) < 1: - sys.stderr.write('\"' + path + '\" has no certificate data.') + sys.stderr.write('Backup file "%s" contains no certificate data.\n' \ + % path) return -1 data = str(data) try: - f = file(path, 'wb+') - except: - sys.stderr.write('Unable to create \" ' + path + '\" for writing.\n') + f = file(cert_path, 'wb+') + except Exception, e: + sys.stderr.write('Unable to open certificate file "%s" for writing: %s\n' \ + % (cert_path, str(e))) return -1 - os.chmod(path, mode) - f.write(data + '\n') - os.chown(path, uid, gid) - f.close() - return None + try: + os.chown(path, uid, gid) + os.chmod(path, mode) + f.write(data) + f.write('\n') + f.close() + except Exception, e: + sys.stderr.write('Unable to restore certificate file "%s": %s\n' \ + % (cert_path, str(e))) + return -1 + return None def luci_restore(argv): - sys.stderr = null - import ZODB + sys.stderr = verbose from ZODB.FileStorage import FileStorage from ZODB.DB import DB - import OFS from OFS.Application import AppInitializer - import OFS.Folder import AccessControl import AccessControl.User - from AccessControl.AuthEncoding import SSHADigestScheme from AccessControl.SecurityManagement import newSecurityManager import transaction - import Products.CMFCore - import Products.CMFCore.MemberDataTool import App.ImageFile - import Products.PluggableAuthService.plugins.ZODBUserManager - import BTrees.OOBTree from DateTime import DateTime + App.ImageFile.__init__ = lambda x, y: None sys.stderr = orig_stderr @@ -337,34 +351,40 @@ conn = db.open() except IOError, e: if e[0] == 11: - sys.stderr.write('It appears that Luci is running. Please stop Luci before attempting to restore your installation.\n') + sys.stderr.write('It appears that the luci service is running.\n') + sys.stderr.write('You must stop the luci service before using this tool restore from a backup.\n') return -1 else: - sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n') + sys.stderr.write('Unable to open the Luci database "%s": %s\n' \ + % (dbfn, str(e))) return -1 except Exception, e: - sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n') + sys.stderr.write('Unable to open the Luci database "%s": %s\n' \ + % (dbfn, str(e))) return -1 try: node = xml.dom.minidom.parse(backupfn) - except: - sys.stderr.write('Unable to open the Luci backup file \"'+ backupfn +'\"\n') + except Exception, e: + sys.stderr.write('Unable to parse backup data contained in file "%s": %s\n' \ + % (backupfn, str(e))) return -1 node = node.getElementsByTagName('luci') if not node or len(node) < 1: - sys.stderr.write('Backup file is missing the \'luci\' tag\n') + sys.stderr.write('Backup file "%s" is missing the "luci" XML tag.\n' \ + % backupfn) return -1 node = node[0].getElementsByTagName('backupData') if not node or len(node) < 1: - sys.stderr.write('Backup file is missing the \'backupData\' tag\n') + sys.stderr.write('Backup file "%s" is missing the "backupData" XML tag\n' \ + % backupfn) return -1 - node = node[0] + node = node[0] try: - sys.stderr = null + sys.stderr = verbose tempuser = AccessControl.User.UnrestrictedUser('admin', '', ('manage','Manager', 'Owner', 'View', 'Authenticated'), []) @@ -373,9 +393,10 @@ app = conn.root()['Application'] AppInitializer(app).initialize() sys.stderr = orig_stderr - except: + except Exception, e: sys.stderr = orig_stderr - sys.stderr.write('An error occurred while initializing the Luci installation for restoration from backup\n') + sys.stderr.write('An error occurred while restoring from backup file "%s": %s\n' \ + % (backupfn, str(e))) return -1 try: @@ -383,52 +404,59 @@ portal_mem = app.luci.portal_membership portal_reg = app.luci.portal_registration if not (acl_users and len(acl_users) and portal_mem and portal_reg): - raise - except: - sys.stderr.write('Your Luci installation appears to be corrupt.\n') + raise Exception, 'no users are present' + except Exception, e: + sys.stderr.write('Your Luci installation appears to be corrupt: %s' % str(e)) return -1 userList = node.getElementsByTagName('userList') if not userList or len(userList) < 1: - sys.stderr.write('Your backup file contains no users. At the very least, the admin user must exist. Please check that your backup file is not corrupt.\n') + sys.stderr.write('Backup file "%s" contains no users.\n' % backupfn) + sys.stderr.write('The admin user must exist.\n') + sys.stderr.write('Please check that your backup file is not corrupt.\n') return -1 userList = userList[0].getElementsByTagName('user') if not userList or len(userList) < 1: - sys.stderr.write('Your backup file contains no users. At the very least, the admin user must exist. Please check that your backup file is not corrupt.\n') + sys.stderr.write('Backup file "%s" contains no users.\n' % backupfn) + sys.stderr.write('The admin user must exist.\n') + sys.stderr.write('Please check that your backup file is not corrupt.\n') return -1 for u in userList: - id = u.getAttribute('id') - if not id: + uid = u.getAttribute('id') + if not uid: transaction.abort() - sys.stderr.write('Missing ID for user\n') + sys.stderr.write('Missing the id attribute for a user in backup file "%s"\n' \ + % backupfn) return -1 - id = str(id) + uid = str(uid) passwd = u.getAttribute('passwd') if not passwd: transaction.abort() - sys.stderr.write('Missing password for user \"' + id + '\"\n') + sys.stderr.write('Missing password for user "%s" in backup file "%s"\n' \ + % (uid, backupfn)) return -1 passwd = str(passwd) - if id == 'admin': + if uid == 'admin': try: acl_users._user_passwords['admin'] = passwd - except: + except Exception, e: transaction.abort() - sys.stderr.write('Unable to restore admin password.') + sys.stderr.write('Unable to restore admin password from backup file "%s": %s\n' \ + % (backupfn, str(e))) return -1 else: email = u.getAttribute('email') if not email: - email = id + '@luci.example.org' + email = '%s@luci.example.org' % uid else: email = str(email) props = { - 'username': id, + 'username': uid, 'roles': [ 'Member' ], 'domains': [], 'email': email, @@ -449,34 +477,38 @@ if must_change_passwd == 'True' or '1': props['must_change_password'] = True - portal_reg.addMember(id, passwd, props) + portal_reg.addMember(uid, passwd, props) - member = portal_mem.getMemberById(id) + member = portal_mem.getMemberById(uid) if not member: transaction.abort() - sys.stderr.write('An error occurred while restoring the user \"' + id + '\"\n') + sys.stderr.write('An error occurred while restoring the user "%s" from backup file "%s"\n' \ + % (uid, backupfn)) return -1 try: aclu = app.luci.acl_users.source_users if aclu and len(aclu): - aclu._user_passwords[id] = passwd + aclu._user_passwords[uid] = passwd else: - raise - except: + raise Exception, 'unable to set password for %s' % uid + except Exception, e: transaction.abort() - sys.stderr.write('An error occurred while restoring the password for user \"' + id + '\"\n') + sys.stderr.write('An error occurred while restoring the password for user "%s" from backup file "%s": %s\n' + % (uid, backupfn, str(e))) return -1 - verbose.write('Added user \"' + id + '\"\n') + verbose.write('Added user "%s"' % uid) transaction.commit() try: x = app.luci.systems.storage if not x: raise - except: + except Exception, e: transaction.abort() - sys.stderr.write('Cannot find the Luci storage systems directory. Your Luci installation may be corrupt.\n') + sys.stderr.write('Cannot find the Luci storage systems directory.\n') + sys.stderr.write('Your Luci installation may be corrupt.\n') + sys.stderr.write('Server error: %s\n' % str(e)) return -1 systemList = node.getElementsByTagName('systemList') @@ -488,32 +520,33 @@ verbose.write('No storage systems to add\n') for s in systemList: - id = s.getAttribute('id') - if not id: + uid = s.getAttribute('id') + if not uid: transaction.abort() sys.stderr.write('Missing ID for storage system. Your backup may be corrupt.\n') return -1 - id = str(id) + uid = str(uid) try: title = str(s.getAttribute('title')) except: title = '__luci__:system' - x.manage_addFolder(id, title) + x.manage_addFolder(uid, title) try: - new_system = app.luci.systems.storage.get(id) + new_system = app.luci.systems.storage.get(uid) if not new_system: raise new_system.manage_acquiredPermissions([]) - new_system.manage_role('View', ['Access contents information','View']) - except: + new_system.manage_role('View', [ 'Access contents information', 'View' ]) + except Exception, e: transaction.abort() - sys.stderr.write('An error occurred while restoring storage system \"' + id + '\"\n') + sys.stderr.write('An error occurred while restoring storage system "%s": %s\n' \ + % (uid, str(e))) return -1 userPerms = s.getElementsByTagName('permList') if not userPerms or len(userPerms) < 1: - verbose.write('Added storage system \"' + id + '\"\n') + verbose.write('Added storage system "%s"\n' % uid) continue userPerms = userPerms[0].getElementsByTagName('ref') for i in userPerms: @@ -522,20 +555,23 @@ continue try: new_system.manage_setLocalRoles(newuser, ['View']) - verbose.write('Added view permission to storage system \"' + id + '\" for \"' + newuser + '\"\n') - except: - sys.stderr.write('An error occurred while restoring permission for storage system \"' + id + '\" for user \"' + newuser + '\"\n') + verbose.write('Added view permission to storage system "%s" for "%s"\n' \ + % (uid, newuser)) + except Exception, e: + sys.stderr.write('An error occurred while restoring permission for storage system "%s" for "%s": %s\n' \ + % (uid, newuser, str(e))) - verbose.write('Added storage system \"' + id + '\"\n') + verbose.write('Added storage system "%s"\n' % uid) transaction.commit() try: x = app.luci.systems.cluster if not x: raise - except: + except Exception, e: transaction.abort() sys.stderr.write('Cannot find the Luci cluster directory. Your Luci installation may be corrupt.\n') + sys.stderr.write('Error reported: %s\n' % str(e)) return -1 clusterList = node.getElementsByTagName('clusterList') @@ -547,12 +583,12 @@ verbose.write('No clusters to add\n') for c in clusterList: - id = c.getAttribute('id') - if not id: + uid = c.getAttribute('id') + if not uid: transaction.abort() - sys.stderr.write('Cluster element is missing id\n') + sys.stderr.write('Cluster element is missing id attribute\n') return -1 - id = str(id) + uid = str(id) title = c.getAttribute('title') if not title: @@ -561,16 +597,17 @@ title = str(title) try: - x.manage_addFolder(id, title) - new_cluster = app.luci.systems.cluster.get(id) + x.manage_addFolder(uid, title) + new_cluster = app.luci.systems.cluster.get(uid) if not new_cluster: raise new_cluster.manage_acquiredPermissions([]) - new_cluster.manage_role('View', ['Access contents information','View']) - except: + new_cluster.manage_role('View', [ 'Access contents information', 'View' ]) + except Exception, e: transaction.abort() - sys.stderr.write('An error occurred while restoring the cluster \"' + id + '\"\n') + sys.stderr.write('An error occurred while restoring the cluster "%s": %s\n' \ + % (uid, str(e))) return -1 viewperm = list() @@ -586,55 +623,62 @@ try: new_cluster.manage_setLocalRoles(newuser, ['View']) - verbose.write('Added view permission to cluster \"' + id + '\" for \"' + newuser + '\"\n') - except: - sys.stderr.write('An error occurred while restoring permission for cluster \"' + id + '\" for user \"' + newuser + '\"\n') + verbose.write('Added view permission to cluster "%s" for "%s"\n' \ + % (uid, newuser)) + except Exception, e: + sys.stderr.write('An error occurred while restoring permission for cluster "%s" for "%s": %s' \ + % (uid, newuser, str(e))) viewperm.append(newuser) clusterSystems = c.getElementsByTagName('csystemList') if not clusterSystems or len(clusterSystems) < 1: - verbose.write('Cluster \"' + id + '\" has no storage systems\n') + verbose.write('Cluster "%s" has no storage systems\n' % uid) else: clusterSystems = clusterSystems[0].getElementsByTagName('csystem') for i in clusterSystems: newsys = i.getAttribute('id') if not newsys: transaction.abort() - sys.stderr.write('Storage system missing name for cluster \"' + id + '\"\n') + sys.stderr.write('Storage system missing id attribute for cluster "%s"\n' \ + % uid) return -1 newsys = str(newsys) stitle = i.getAttribute('title') if not stitle: - stitle = '__luci__:csystem:' + id + stitle = '__luci__:csystem:%s' % uid else: stitle = str(stitle) try: new_cluster.manage_addFolder(newsys, stitle) - newcs = app.luci.systems.cluster.get(id).get(newsys) + newcs = app.luci.systems.cluster.get(uid).get(newsys) if not newcs: raise newcs.manage_acquiredPermissions([]) - newcs.manage_role('View', ['Access contents information','View']) - except: + newcs.manage_role('View', [ 'Access contents information', 'View' ]) + except Exception, e: transaction.abort() - sys.stderr.write('An error occurred while restoring the storage system \"' + newsys + '\" for cluster \"' + id + '\"\n') + sys.stderr.write('An error occurred while restoring the storage system "%s" for cluster "%s": %s' \ + % (newsys, uid, str(e))) return -1 transaction.commit() try: for i in viewperm: newcs.manage_setLocalRoles(i, ['View']) - verbose.write('Added view permission to cluster system \"' + newsys + '\" for \"' + i + '\"\n') + verbose.write('Added view permission to cluster system "%s" for "%s"\n' \ + % (newsys, i)) except: transaction.abort() - sys.stderr.write('An error occurred while restoring permissions for cluster system \"' + newsys + '\" in cluster \"' + id + '\" for user \"' + i + '\"\n') + sys.stderr.write('An error occurred while restoring permissions for cluster system "%s" in cluster "%s" for user "%s"\n' \ + % (newsys, uid, i)) return -1 - verbose.write('Added storage system \"' + newsys + '\" for cluster \"' + id + '\"\n') + verbose.write('Added storage system "%s" for cluster "%s"\n' \ + % (newsys, uid)) - verbose.write('Added cluster \"' + id + '\"\n') + verbose.write('Added cluster "%s"\n' % uid) transaction.commit() transaction.commit() @@ -645,34 +689,35 @@ certList = node.getElementsByTagName('certificateList') if not certList or len(certList) < 1: - sys.stderr.write('No certificate data was found.\n') + sys.stderr.write('Backup file "%s" contains no certificate data.\n' \ + % backupfn) return -1 - if luci_restore_certs(certList): + if luci_restore_certs(backupfn, certList): sys.stderr.write('An error occurred while restoring certificate data.\n') return -1 return 0 # This function's ability to work is dependent -# upon the structure of @dict -def dataToXML(doc, dict, tltag): +# upon the structure of @ddict +def dataToXML(doc, ddict, tltag): node = doc.createElement(tltag) - for i in dict: - if isinstance(dict[i], types.DictType): + for i in ddict: + if isinstance(ddict[i], types.DictType): if i[-4:] == 'List': tagname = i else: tagname = tltag[:-4] - temp = dataToXML(doc, dict[i], tagname) + temp = dataToXML(doc, ddict[i], tagname) node.appendChild(temp) - elif isinstance(dict[i], types.StringType) or isinstance(dict[i], types.IntType): - node.setAttribute(i, str(dict[i])) - elif isinstance(dict[i], types.ListType): - if len(dict[i]) < 1: + elif isinstance(ddict[i], types.StringType) or isinstance(ddict[i], types.IntType): + node.setAttribute(i, str(ddict[i])) + elif isinstance(ddict[i], types.ListType): + if len(ddict[i]) < 1: continue temp = doc.createElement(i) - for x in dict[i]: + for x in ddict[i]: t = doc.createElement('ref') t.setAttribute('name', x) temp.appendChild(t.cloneNode(True)) @@ -680,24 +725,16 @@ return node.cloneNode(True) def luci_backup(argv): - sys.stderr = null - import ZODB + sys.stderr = verbose from ZODB.FileStorage import FileStorage from ZODB.DB import DB - import OFS from OFS.Application import AppInitializer - import OFS.Folder import AccessControl import AccessControl.User - from AccessControl.AuthEncoding import SSHADigestScheme from AccessControl.SecurityManagement import newSecurityManager import transaction - import Products.CMFCore - import Products.CMFCore.MemberDataTool - from CMFPlone.utils import getToolByName + import CMFPlone import App.ImageFile - import Products.PluggableAuthService.plugins.ZODBUserManager - import BTrees.OOBTree App.ImageFile.__init__ = lambda x, y: None sys.stderr = orig_stderr @@ -706,11 +743,6 @@ else: dbfn = LUCI_DB_PATH - if len(argv) > 1: - backupfn = argv[1] - else: - backupfn = LUCI_BACKUP_PATH - try: fs = FileStorage(dbfn) db = DB(fs) @@ -721,14 +753,16 @@ sys.stderr.write('It appears that Luci is running. Please stop Luci before attempting to backup your installation.\n') return -1 else: - sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n') + sys.stderr.write('Unable to open the Luci database "%s: %s\n' \ + % (dbfn, str(e))) return -1 except Exception, e: - sys.stderr.write('Unable to open the Luci database \"' + dbfn + '\":' + str(e) + '\n') + sys.stderr.write('Unable to open the Luci database "%s: %s\n' \ + % (dbfn, str(e))) return -1 try: - sys.stderr = null + sys.stderr = verbose tempuser = AccessControl.User.UnrestrictedUser('admin', '', ('manage','Manager', 'Owner', 'View', 'Authenticated'), []) @@ -737,9 +771,10 @@ app = conn.root()['Application'] AppInitializer(app).initialize() sys.stderr = orig_stderr - except: + except Exception, e: sys.stderr = orig_stderr - sys.stderr.write('An error occurred while initializing the Luci installation for restoration from backup\n') + sys.stderr.write('An error occurred while initializing luci for restore from backup: %s\n' \ + % str(e)) return -1 app.luci.portal_memberdata.pruneMemberDataContents() @@ -748,9 +783,10 @@ try: acl_users = app.acl_users.users if not (acl_users and len(acl_users)): - raise - except: - sys.stderr.write('Your Luci installation appears to be corrupt.\n') + raise Exception, 'no luci users exist' + except Exception, e: + sys.stderr.write('Your Luci installation appears to be corrupt: %s\n' \ + % str(e)) return -1 users = {} @@ -760,14 +796,15 @@ try: acl_users = app.acl_users.users if len(acl_users) < 1: - raise + raise Exception, 'no users exist' + users['admin'] = { 'id': 'admin', 'name': 'admin', 'passwd': app.acl_users.users._user_passwords['admin'] } except: - sys.stderr.write('Unable to find the admin user.\n') + sys.stderr.write('Unable to find the luci admin user.\n') return -1 acl_users = app.luci.acl_users.source_users @@ -779,33 +816,39 @@ 'name': i[0], 'passwd': i[1] } - except: + except Exception, e: try: - sys.stderr.write('An error occurred while saving details for user \"' + i[0] + '\"\n') + sys.stderr.write('An error occurred while saving details for user "%s": %s' \ + % (i[0], str(e))) except: - sys.stderr.write('An error occurred while saving user information.') + sys.stderr.write('An error occurred while saving user information: %s' \ + % str(e)) return -1 try: - membertool = getToolByName(app.luci, 'portal_membership') + membertool = CMFPlone.utils.getToolByName(app.luci, 'portal_membership') if not membertool: - raise + raise Exception, 'unable to retrieve luci users' + for mem in membertool.listMembers(): try: for i in [ 'login_time', 'last_login_time', 'must_change_password', 'email' ]: prop = mem.getProperty(i) if prop != '': users[mem.id][i] = str(prop) - except: + except Exception, e1: + verbose.write('Error retrieving member properties: %s\n' \ + % str(e1)) continue - except: - pass - + except Exception, e: + verbose.write('Error retrieving luci user data: %s\n' % str(e)) + try: storagedir = app.luci.systems.storage clusterdir = app.luci.systems.cluster - except: - sys.stderr.write('Your Luci installation appears to be corrupt.') + except Exception, e: + sys.stderr.write('Your Luci installation appears to be corrupt.\n') + sys.stderr.write('Server error: %s\n' % str(e)) return -1 if storagedir and len(storagedir): @@ -822,7 +865,7 @@ systems[i[0]]['permList'] = map(lambda x: x[0], filter(lambda x: len(x) > 1 and 'View' in x[1], roles.items())) else: systems[i[0]]['permList'] = {} - + if clusterdir and len(clusterdir): for i in clusterdir.objectItems(): cluster_name = i[0] @@ -875,7 +918,7 @@ if len(output) < 1: raise except: - sys.stderr.write('Unable to read \"' + i['id'] + '\"\n') + sys.stderr.write('Unable to read "%s"\n' % i['id']) # An error backing up anything other than the config # is fatal. if i['type'] != 'config': @@ -895,195 +938,182 @@ return doc - def _execWithCaptureErrorStatus(command, argv, searchPath = 0, root = '/', stdin = 0, catchfd = 1, catcherrfd = 2, closefd = -1): - if not os.access (root + command, os.X_OK): - raise RuntimeError, command + " can not be run" + if not os.access (root + command, os.X_OK): + raise RuntimeError, '%s%s is not executable' % (root, command) - (read, write) = os.pipe() - (read_err,write_err) = os.pipe() - - childpid = os.fork() - if (not childpid): - # child - if (root and root != '/'): os.chroot (root) - if isinstance(catchfd, tuple): - for fd in catchfd: - os.dup2(write, fd) - else: - os.dup2(write, catchfd) - os.close(write) - os.close(read) - - if isinstance(catcherrfd, tuple): - for fd in catcherrfd: - os.dup2(write_err, fd) - else: - os.dup2(write_err, catcherrfd) - os.close(write_err) - os.close(read_err) - - if closefd != -1: - os.close(closefd) - - if stdin: - os.dup2(stdin, 0) - os.close(stdin) - - if (searchPath): - os.execvp(command, argv) - else: - os.execv(command, argv) - # will never come here - - os.close(write) - os.close(write_err) - - rc = "" - rc_err = "" - in_list = [read, read_err] - while len(in_list) != 0: - i,o,e = select.select(in_list, [], [], 0.1) - for fd in i: - if fd == read: - s = os.read(read, 1000) - if s == '': - in_list.remove(read) - rc = rc + s - if fd == read_err: - s = os.read(read_err, 1000) - if s == '': - in_list.remove(read_err) - rc_err = rc_err + s - - os.close(read) - os.close(read_err) - - status = -1 - try: - (pid, status) = os.waitpid(childpid, 0) - except OSError, (errno, msg): - sys.stderr.write(__name__ + 'waitpid: ' + msg + '\n') - - if os.WIFEXITED(status): - status = os.WEXITSTATUS(status) - else: - status = -1 - - return (rc, rc_err, status) + (read, write) = os.pipe() + (read_err, write_err) = os.pipe() + childpid = os.fork() + if (not childpid): + # child + if (root and root != '/'): + os.chroot(root) + if isinstance(catchfd, tuple): + for fd in catchfd: + os.dup2(write, fd) + else: + os.dup2(write, catchfd) + os.close(write) + os.close(read) + + if isinstance(catcherrfd, tuple): + for fd in catcherrfd: + os.dup2(write_err, fd) + else: + os.dup2(write_err, catcherrfd) + os.close(write_err) + os.close(read_err) + + if closefd != -1: + os.close(closefd) + + if stdin: + os.dup2(stdin, 0) + os.close(stdin) + if (searchPath): + os.execvp(command, argv) + else: + os.execv(command, argv) + # will never come here + os.close(write) + os.close(write_err) + rc = "" + rc_err = "" + in_list = [read, read_err] + while len(in_list) != 0: + i, o, e = select.select(in_list, [], [], 0.1) + for fd in i: + if fd == read: + s = os.read(read, 1024) + if s == '': + in_list.remove(read) + rc = rc + s + if fd == read_err: + s = os.read(read_err, 1024) + if s == '': + in_list.remove(read_err) + rc_err = rc_err + s + + os.close(read) + os.close(read_err) + + status = -1 + try: + (pid, status) = os.waitpid(childpid, 0) + except OSError, (errno, msg): + sys.stderr.write('%s waitpid: %s\n' % (__name__ , msg)) + if os.WIFEXITED(status): + status = os.WEXITSTATUS(status) + else: + status = -1 + return (rc, rc_err, status) def luci_initialized(): - # existence of privkey.pem file and - # admin password (not the one Data.fs comes with) - # mean that luci has been initialized - b1 = get_default_passwd_reset_flag() - b2 = os.access(SSL_PRIVKEY_PATH, os.F_OK) - return b1 and b2 - - + # existence of privkey.pem file and + # admin password (not the one Data.fs comes with) + # mean that luci has been initialized + b1 = get_default_passwd_reset_flag() + b2 = os.access(SSL_PRIVKEY_PATH, os.F_OK) + return b1 and b2 def generate_ssl_certs(): - command = '/bin/rm' - args = [command, '-f', SSL_PRIVKEY_PATH, SSL_PUBKEY_PATH] - _execWithCaptureErrorStatus(command, args) - - # /usr/bin/openssl genrsa -out /var/lib/luci/var/certs/privkey.pem 2048 > /dev/null 2>&1 - command = '/usr/bin/openssl' - args = [command, 'genrsa', '-out', SSL_PRIVKEY_PATH, '2048'] - _execWithCaptureErrorStatus(command, args) - - # /usr/bin/openssl req -new -x509 -key /var/lib/luci/var/certs/privkey.pem -out /var/lib/luci/var/certs/cacert.pem -days 1825 -config /var/lib/luci/var/certs/cacert.config - command = '/usr/bin/openssl' - args = [command, 'req', '-new', '-x509', '-key', SSL_PRIVKEY_PATH, '-out', SSL_PUBKEY_PATH, '-days', '1825', '-config', SSL_KEYCONFIG_PATH] - _execWithCaptureErrorStatus(command, args) - - # take ownership and restrict access - try: - uid, gid = get_luci_uid_gid() - os.chown(SSL_PRIVKEY_PATH, uid, gid) - os.chown(SSL_PUBKEY_PATH, uid, gid) - os.chmod(SSL_PRIVKEY_PATH, 0600) - os.chmod(SSL_PUBKEY_PATH, 0644) - except: - command = '/bin/rm' - args = [command, '-f', SSL_PRIVKEY_PATH, SSL_PUBKEY_PATH] - _execWithCaptureErrorStatus(command, args) - return False - - return True - - -def restart_message(): - print - print - print 'Restart the Luci server for changes to take effect' - print 'eg. service luci restart' - print - return - + command = '/bin/rm' + args = [command, '-f', SSL_PRIVKEY_PATH, SSL_PUBKEY_PATH] + _execWithCaptureErrorStatus(command, args) + + # /usr/bin/openssl genrsa -out /var/lib/luci/var/certs/privkey.pem 2048 > /dev/null 2>&1 + command = '/usr/bin/openssl' + args = [command, 'genrsa', '-out', SSL_PRIVKEY_PATH, '2048'] + _execWithCaptureErrorStatus(command, args) + + # /usr/bin/openssl req -new -x509 -key /var/lib/luci/var/certs/privkey.pem -out /var/lib/luci/var/certs/cacert.pem -days 1825 -config /var/lib/luci/var/certs/cacert.config + command = '/usr/bin/openssl' + args = [command, 'req', '-new', '-x509', '-key', SSL_PRIVKEY_PATH, '-out', SSL_PUBKEY_PATH, '-days', '1825', '-config', SSL_KEYCONFIG_PATH] + _execWithCaptureErrorStatus(command, args) + # take ownership and restrict access + try: + uid, gid = get_luci_uid_gid() + os.chown(SSL_PRIVKEY_PATH, uid, gid) + os.chown(SSL_PUBKEY_PATH, uid, gid) + os.chmod(SSL_PRIVKEY_PATH, 0600) + os.chmod(SSL_PUBKEY_PATH, 0644) + except Exception, e: + verbose.write('Error setting SSL cert file perms: %s\n' % str(e)) + command = '/bin/rm' + args = [command, '-f', SSL_PRIVKEY_PATH, SSL_PUBKEY_PATH] + _execWithCaptureErrorStatus(command, args) + return False + return True +def restart_message(): + print + print + print 'Restart the Luci server for changes to take effect' + print 'eg. service luci restart' + print + return def init(argv): if luci_initialized(): sys.stderr.write('Luci site has been already initialized.\n') sys.stderr.write('If you want to reset admin password, execute\n') - sys.stderr.write('\t' + argv[0] + ' password\n') + sys.stderr.write('\t%s password\n' % argv[0]) sys.exit(1) - + print 'Initializing the Luci server\n' - + print '\nCreating the \'admin\' user\n' - password = read_passwd('Enter password: ', 'Confirm password: ') + pwd_str = read_passwd('Enter password: ', 'Confirm password: ') print '\nPlease wait...' - if not set_zope_passwd('admin', password): + if not set_zope_passwd('admin', pwd_str): restore_luci_db_fsattr() print 'The admin password has been successfully set.' else: sys.stderr.write('Unable to set the admin user\'s password.\n') sys.exit(1) - + print 'Generating SSL certificates...' if generate_ssl_certs() == False: sys.stderr.write('failed. exiting ...\n') sys.exit(1) - + print 'Luci server has been successfully initialized' restart_message() - - return + return def password(argv): - password = None + pwd_str = None if '--random' in argv: - print 'Resetting the admin user\'s password to some random value\n' + print 'Setting the admin user\'s password to a random value.\n' try: rand = open('/dev/urandom', 'r') - password = rand.read(16) + pwd_str = rand.read(16) rand.close() - except: - sys.stderr.write('Unable to read from /dev/urandom\n') + except Exception, e: + sys.stderr.write('Unable to read from /dev/urandom: %s\n' % str(e)) sys.exit(1) else: if not luci_initialized(): sys.stderr.write('The Luci site has not been initialized.\n') - sys.stderr.write('To initialize it, execute\n') - sys.stderr.write('\t' + argv[0] + ' init\n') + sys.stderr.write('To initialize it, execute:\n') + sys.stderr.write('\t%s init\n' % argv[0]) sys.exit(1) - + print 'Resetting the admin user\'s password\n' - password = read_passwd('Enter new password: ', 'Confirm password: ') - + pwd_str = read_passwd('Enter new password: ', 'Confirm password: ') + print '\nPlease wait...' - if not set_zope_passwd('admin', password): + if not set_zope_passwd('admin', pwd_str): print 'The admin password has been successfully reset.' else: sys.stderr.write('Unable to set the admin user\'s password.\n') @@ -1093,8 +1123,7 @@ return - -def backup(argv): +def backup_db(argv): # If the site hasn't been initialized, there's nothing to # save, and luci_backup() will fail if not luci_initialized(): @@ -1106,7 +1135,8 @@ try: os.umask(077) - except: pass + except: + pass doc = luci_backup(argv[2:]) restore_luci_db_fsattr() @@ -1118,18 +1148,20 @@ # The LUCI_BACKUP_DIR must not be world-writable # as the code below is obviously not safe against # races. - stat = os.stat(LUCI_BACKUP_PATH) + os.stat(LUCI_BACKUP_PATH) trynum = 1 basename = '/luci_backup-' while True: - oldbackup = LUCI_BACKUP_DIR + basename + str(trynum) + '.xml' + oldbackup = '%s%s%s.xml' % (LUCI_BACKUP_DIR, basename, str(trynum)) if not os.path.exists(oldbackup): try: os.rename(LUCI_BACKUP_PATH, oldbackup) - except: - sys.stderr.stderr('Unable to rename the existing backup file.\n') + except Exception, e1: + sys.stderr.write('Unable to rename the existing backup file "%s" to "%s": %s\n' \ + % (LUCI_BACKUP_PATH, oldbackup, str(e1))) sys.stderr.write('The Luci backup failed.\n') + sys.exit(1) break trynum += 1 except OSError, e: @@ -1139,31 +1171,37 @@ try: f = file(LUCI_BACKUP_PATH, 'wb+') except: - sys.stderr.write('Unable to open \"' + LUCI_BACKUP_PATH + '\" to write backup.\n') + sys.stderr.write('Unable to open the file "%s" to write backup data.\n' + % LUCI_BACKUP_PATH) sys.stderr.write('The Luci backup failed.\n') sys.exit(1) try: os.chmod(LUCI_BACKUP_PATH, 0600) except OSError, e: - sys.stderr.write('An error occurred while making \"' + LUCI_BACKUP_PATH + '\" read-only: ' + e + '\n') + sys.stderr.write('An error occurred while setting file permissions on backup file "%s": %s\n' \ + % (LUCI_BACKUP_PATH, str(e))) sys.stderr.write('Please check that this file is not world-readable.\n') try: f.write(doc.toprettyxml()) f.close() - except: - sys.stderr.write('The Luci backup failed.\n') + except Exception, e: + sys.stderr.write('An error occurred while writing backup file "%s": %s\n' \ + % (LUCI_BACKUP_PATH, str(e))) + sys.stderr.write('Luci backup failed.\n') sys.exit(1) - print 'Luci backup was successful.\nThe backup data is contained in the file \"' + LUCI_BACKUP_PATH + '\"' - + print 'The luci backup procedure was successful.' + print 'Backup data is contained in the file "%s"' % LUCI_BACKUP_PATH -def restore(argv): +def restore_db(argv): print 'Restoring the Luci server...' - try: os.umask(077) - except: pass + try: + os.umask(077) + except: + pass if luci_restore(argv[2:]): ret = False @@ -1179,67 +1217,61 @@ return ret - def luci_help(argv): - print 'Usage:' - print argv[0] + ' [init|backup|restore|password|help]' - print - print '\tinit: initialize Luci site' - print '\tpassword: reset admin password' - print '\t\t--random: reset admin password to random value (disable account)' - print '\tbackup: backup Luci site to a file' - print '\trestore: restore Luci site from backup' - print '\thelp: this help message' - print - - + print 'Usage:' + print argv[0] + ' [init|backup|restore|password|help]' + print + print '\tinit: initialize Luci site' + print '\tpassword: reset admin password' + print '\t\t--random: reset admin password to random value (disable account)' + print '\tbackup: backup Luci site to a file' + print '\trestore: restore Luci site from backup' + print '\thelp: this help message' + print def test_luci_installation(): - # perform basic checks - # TODO: do more tests - - # check if luci user and group are present on the system - try: - get_luci_uid_gid() - except: - sys.stderr.write('There is a problem with luci installation!\n') - sys.stderr.write('Mising luci\'s system account and group') - sys.stderr.write('Recommended action: reinstall luci\n\n') - sys.exit(3) - - return True + # perform basic checks + # TODO: do more tests + # check if luci user and group are present on the system + try: + get_luci_uid_gid() + except: + sys.stderr.write('There is a problem with luci installation.\n') + sys.stderr.write('Mising luci\'s system account and group.\n') + sys.stderr.write('Recommended action: reinstall luci.\n\n') + sys.exit(3) + return True def main(argv): - if len(argv) < 2: - luci_help(argv) - sys.exit(1) - - # only root should run this - if os.getuid() != 0: - sys.stderr.write('Only \'root\' can run ' + argv[0] + '\n') - sys.stderr.write('Try again with root privileges.\n') - sys.exit(2) - - # test if luci installation is OK - test_luci_installation() - - if 'init' in argv: - init(argv) - elif 'backup' in argv: - backup(argv) - elif 'restore' in argv: - restore(argv) - elif 'password' in argv: - password(argv) - elif 'help' in argv: - luci_help(argv) - else: - sys.stderr.write('Unknown command\n\n') - luci_help(argv) - sys.exit(1) + if len(argv) < 2: + luci_help(argv) + sys.exit(1) + # only root should run this + if os.getuid() != 0: + sys.stderr.write('Only "root" can run %s\n' % argv[0]) + sys.stderr.write('Try again with root privileges.\n') + sys.exit(2) + + # test if luci installation is OK + test_luci_installation() + + if 'init' in argv: + init(argv) + elif 'backup' in argv: + backup_db(argv) + elif 'restore' in argv: + restore_db(argv) + elif 'password' in argv: + password(argv) + elif 'help' in argv: + luci_help(argv) + else: + sys.stderr.write('Unknown command\n\n') + luci_help(argv) + sys.exit(1) # If called from the command line if __name__ == '__main__': - main(sys.argv) + main(sys.argv)