Imported Debian patch 4.0.5-6~numeezy
This commit is contained in:
committed by
Mario Fetka
parent
c44de33144
commit
10dfc9587b
@@ -17,65 +17,34 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import ldif
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import random
|
||||
import traceback
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform import services
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython import ipaldap
|
||||
|
||||
from ipaserver.install import installutils
|
||||
from ipaserver.install import dsinstance
|
||||
from ipaserver.install import schemaupdate
|
||||
from ipaserver.install import ldapupdate
|
||||
from ipaserver.install import service
|
||||
|
||||
DSBASE = paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE
|
||||
DSE = 'dse.ldif'
|
||||
|
||||
|
||||
class GetEntryFromLDIF(ldif.LDIFParser):
|
||||
"""
|
||||
LDIF parser.
|
||||
To get results, method parse() must be called first, then method
|
||||
get_results() which return parsed entries
|
||||
"""
|
||||
def __init__(self, input_file, entries_dn=[]):
|
||||
"""
|
||||
Parse LDIF file.
|
||||
:param input_file: an LDIF file to be parsed
|
||||
:param entries_dn: list of DN which will be returned. All entries are
|
||||
returned if list is empty.
|
||||
"""
|
||||
ldif.LDIFParser.__init__(self, input_file)
|
||||
self.entries_dn = entries_dn
|
||||
self.results = {}
|
||||
|
||||
def get_results(self):
|
||||
"""
|
||||
Returns results in dictionary {DN: entry, ...}
|
||||
"""
|
||||
return self.results
|
||||
|
||||
def handle(self, dn, entry):
|
||||
if self.entries_dn and dn not in self.entries_dn:
|
||||
return
|
||||
|
||||
self.results[dn] = entry
|
||||
|
||||
|
||||
class IPAUpgrade(service.Service):
|
||||
"""
|
||||
Update the LDAP data in an instance by turning off all network
|
||||
listeners and updating over ldapi. This way we know the server is
|
||||
quiet.
|
||||
"""
|
||||
def __init__(self, realm_name, files=[], schema_files=[]):
|
||||
def __init__(self, realm_name, files=[], live_run=True, schema_files=[]):
|
||||
"""
|
||||
realm_name: kerberos realm name, used to determine DS instance dir
|
||||
files: list of update files to process. If none use UPDATEDIR
|
||||
live_run: boolean that defines if we are in test or live mode.
|
||||
"""
|
||||
|
||||
ext = ''
|
||||
@@ -84,141 +53,122 @@ class IPAUpgrade(service.Service):
|
||||
h = "%02x" % rand.randint(0,255)
|
||||
ext += h
|
||||
service.Service.__init__(self, "dirsrv")
|
||||
serverid = installutils.realm_to_serverid(realm_name)
|
||||
self.filename = '%s/%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE)
|
||||
self.savefilename = '%s/%s.ipa.%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE, ext)
|
||||
serverid = dsinstance.realm_to_serverid(realm_name)
|
||||
self.filename = '%s/%s' % (DSBASE % serverid, DSE)
|
||||
self.savefilename = '%s/%s.ipa.%s' % (DSBASE % serverid, DSE, ext)
|
||||
self.live_run = live_run
|
||||
self.files = files
|
||||
self.modified = False
|
||||
self.badsyntax = False
|
||||
self.upgradefailed = False
|
||||
self.serverid = serverid
|
||||
self.schema_files = schema_files
|
||||
self.realm = realm_name
|
||||
|
||||
def __start(self):
|
||||
services.service(self.service_name).start(self.serverid, ldapi=True)
|
||||
def __start_nowait(self):
|
||||
# Don't wait here because we've turned off port 389. The connection
|
||||
# we make will wait for the socket.
|
||||
super(IPAUpgrade, self).start(wait=False)
|
||||
|
||||
def __stop_instance(self):
|
||||
"""Stop only the main DS instance"""
|
||||
super(IPAUpgrade, self).stop(self.serverid)
|
||||
|
||||
def create_instance(self):
|
||||
ds_running = super(IPAUpgrade, self).is_running()
|
||||
if ds_running:
|
||||
self.step("stopping directory server", self.__stop_instance)
|
||||
self.step("stopping directory server", self.__stop_instance)
|
||||
self.step("saving configuration", self.__save_config)
|
||||
self.step("disabling listeners", self.__disable_listeners)
|
||||
self.step("enabling DS global lock", self.__enable_ds_global_write_lock)
|
||||
self.step("starting directory server", self.__start)
|
||||
self.step("starting directory server", self.__start_nowait)
|
||||
self.step("preparing server upgrade", self.__pre_schema_upgrade)
|
||||
if self.schema_files:
|
||||
self.step("updating schema", self.__update_schema)
|
||||
self.step("upgrading server", self.__upgrade)
|
||||
self.step("stopping directory server", self.__stop_instance)
|
||||
self.step("restoring configuration", self.__restore_config)
|
||||
self.step("starting directory server", self.start)
|
||||
|
||||
self.step("stopping directory server", self.__stop_instance,
|
||||
run_after_failure=True)
|
||||
self.step("restoring configuration", self.__restore_config,
|
||||
run_after_failure=True)
|
||||
if ds_running:
|
||||
self.step("starting directory server", self.start)
|
||||
self.start_creation(start_message="Upgrading IPA:",
|
||||
show_service_name=False)
|
||||
|
||||
def __save_config(self):
|
||||
shutil.copy2(self.filename, self.savefilename)
|
||||
with open(self.filename, "rb") as in_file:
|
||||
parser = GetEntryFromLDIF(in_file, entries_dn=["cn=config"])
|
||||
parser.parse()
|
||||
try:
|
||||
config_entry = parser.get_results()["cn=config"]
|
||||
except KeyError:
|
||||
raise RuntimeError("Unable to find cn=config entry in %s" %
|
||||
self.filename)
|
||||
port = installutils.get_directive(self.filename, 'nsslapd-port',
|
||||
separator=':')
|
||||
security = installutils.get_directive(self.filename, 'nsslapd-security',
|
||||
separator=':')
|
||||
|
||||
try:
|
||||
port = config_entry['nsslapd-port'][0]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
self.backup_state('nsslapd-port', port)
|
||||
|
||||
try:
|
||||
security = config_entry['nsslapd-security'][0]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
self.backup_state('nsslapd-security', security)
|
||||
|
||||
try:
|
||||
global_lock = config_entry['nsslapd-global-backend-lock'][0]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
self.backup_state('nsslapd-global-backend-lock', global_lock)
|
||||
|
||||
def __enable_ds_global_write_lock(self):
|
||||
ldif_outfile = "%s.modified.out" % self.filename
|
||||
with open(ldif_outfile, "wb") as out_file:
|
||||
with open(self.filename, "rb") as in_file:
|
||||
parser = installutils.ModifyLDIF(in_file, out_file)
|
||||
|
||||
parser.replace_value(
|
||||
"cn=config", "nsslapd-global-backend-lock", ["on"])
|
||||
parser.parse()
|
||||
|
||||
shutil.copy2(ldif_outfile, self.filename)
|
||||
self.backup_state('nsslapd-port', port)
|
||||
self.backup_state('nsslapd-security', security)
|
||||
|
||||
def __restore_config(self):
|
||||
port = self.restore_state('nsslapd-port')
|
||||
security = self.restore_state('nsslapd-security')
|
||||
global_lock = self.restore_state('nsslapd-global-backend-lock')
|
||||
|
||||
ldif_outfile = "%s.modified.out" % self.filename
|
||||
with open(ldif_outfile, "wb") as out_file:
|
||||
with open(self.filename, "rb") as in_file:
|
||||
parser = installutils.ModifyLDIF(in_file, out_file)
|
||||
|
||||
if port is not None:
|
||||
parser.replace_value("cn=config", "nsslapd-port", [port])
|
||||
if security is not None:
|
||||
parser.replace_value("cn=config", "nsslapd-security",
|
||||
[security])
|
||||
|
||||
# disable global lock by default
|
||||
parser.remove_value("cn=config", "nsslapd-global-backend-lock")
|
||||
if global_lock is not None:
|
||||
parser.add_value("cn=config", "nsslapd-global-backend-lock",
|
||||
[global_lock])
|
||||
|
||||
parser.parse()
|
||||
|
||||
shutil.copy2(ldif_outfile, self.filename)
|
||||
installutils.set_directive(self.filename, 'nsslapd-port',
|
||||
port, quotes=False, separator=':')
|
||||
installutils.set_directive(self.filename, 'nsslapd-security',
|
||||
security, quotes=False, separator=':')
|
||||
|
||||
def __disable_listeners(self):
|
||||
ldif_outfile = "%s.modified.out" % self.filename
|
||||
with open(ldif_outfile, "wb") as out_file:
|
||||
with open(self.filename, "rb") as in_file:
|
||||
parser = installutils.ModifyLDIF(in_file, out_file)
|
||||
parser.replace_value("cn=config", "nsslapd-port", ["0"])
|
||||
parser.replace_value("cn=config", "nsslapd-security", ["off"])
|
||||
parser.remove_value("cn=config", "nsslapd-ldapientrysearchbase")
|
||||
parser.parse()
|
||||
installutils.set_directive(self.filename, 'nsslapd-port',
|
||||
0, quotes=False, separator=':')
|
||||
installutils.set_directive(self.filename, 'nsslapd-security',
|
||||
'off', quotes=False, separator=':')
|
||||
installutils.set_directive(self.filename, 'nsslapd-ldapientrysearchbase',
|
||||
None, quotes=False, separator=':')
|
||||
|
||||
shutil.copy2(ldif_outfile, self.filename)
|
||||
def __pre_schema_upgrade(self):
|
||||
try:
|
||||
ld = ldapupdate.LDAPUpdate(dm_password='', ldapi=True, live_run=self.live_run, plugins=True)
|
||||
self.modified = (ld.pre_schema_update(ordered=True) or
|
||||
self.modified)
|
||||
except ldapupdate.BadSyntax, e:
|
||||
root_logger.error('Bad syntax in pre schema upgrade %s' % str(e))
|
||||
self.modified = False
|
||||
self.badsyntax = True
|
||||
except Exception, e:
|
||||
# Bad things happened, return gracefully
|
||||
self.modified = False
|
||||
self.upgradefailed = True
|
||||
root_logger.error('Pre schema upgrade failed with %s' % str(e))
|
||||
root_logger.debug('%s', traceback.format_exc())
|
||||
|
||||
def __update_schema(self):
|
||||
self.modified = schemaupdate.update_schema(
|
||||
self.schema_files,
|
||||
dm_password='', ldapi=True) or self.modified
|
||||
dm_password='', ldapi=True, live_run=self.live_run) or self.modified
|
||||
|
||||
def __upgrade(self):
|
||||
try:
|
||||
ld = ldapupdate.LDAPUpdate(dm_password='', ldapi=True)
|
||||
ld = ldapupdate.LDAPUpdate(dm_password='', ldapi=True, live_run=self.live_run, plugins=True)
|
||||
if len(self.files) == 0:
|
||||
self.files = ld.get_all_files(ldapupdate.UPDATES_DIR)
|
||||
self.modified = (ld.update(self.files) or self.modified)
|
||||
except ldapupdate.BadSyntax as e:
|
||||
root_logger.error('Bad syntax in upgrade %s', e)
|
||||
raise
|
||||
except Exception as e:
|
||||
self.modified = (ld.update(self.files, ordered=True) or
|
||||
self.modified)
|
||||
except ldapupdate.BadSyntax, e:
|
||||
root_logger.error('Bad syntax in upgrade %s' % str(e))
|
||||
self.modified = False
|
||||
self.badsyntax = True
|
||||
except Exception, e:
|
||||
# Bad things happened, return gracefully
|
||||
root_logger.error('Upgrade failed with %s', e)
|
||||
self.modified = False
|
||||
self.upgradefailed = True
|
||||
root_logger.error('Upgrade failed with %s' % str(e))
|
||||
root_logger.debug('%s', traceback.format_exc())
|
||||
raise RuntimeError(e)
|
||||
|
||||
def main():
|
||||
if os.getegid() != 0:
|
||||
print "Must be root to set up server"
|
||||
return 1
|
||||
|
||||
update = IPAUpgrade('EXAMPLE.COM')
|
||||
update.create_instance()
|
||||
|
||||
return 0
|
||||
|
||||
try:
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
except SystemExit, e:
|
||||
sys.exit(e)
|
||||
except KeyboardInterrupt, e:
|
||||
sys.exit(1)
|
||||
|
||||
Reference in New Issue
Block a user