From c856fb60737612781fab30760bceeb8bbf6312d9 Mon Sep 17 00:00:00 2001 From: Martin Kosek Date: Fri, 8 Jun 2012 08:31:37 +0200 Subject: Add sysupgrade state file When IPA package is being updated, some of the configuration files are also updated. Sometimes it may be useful to store upgrade meta information for next package upgrades. For example an information that some config file was already updated and we don't want to update it again if user purposedly reverted the change. This patch adds a new StateFile in /var/lib/ipa/sysupgrade which is capable of holding this information. New sysupgrade.py module was created to provide simple API to access the upgrade state information. --- freeipa.spec.in | 5 +++++ install/Makefile.am | 3 +++ install/tools/ipa-server-install | 4 ++++ ipapython/sysrestore.py | 45 +++++++++++++++++++++++++++----------- ipaserver/install/sysupgrade.py | 47 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 ipaserver/install/sysupgrade.py diff --git a/freeipa.spec.in b/freeipa.spec.in index 987ba9082..1ab2db2c2 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -357,6 +357,7 @@ rm %{buildroot}/%{_libdir}/samba/pdb/ipasam.la # and link back. mkdir -p %{buildroot}/%{_sysconfdir}/ipa/html mkdir -p %{buildroot}/%{_localstatedir}/cache/ipa/sysrestore +mkdir -p %{buildroot}/%{_localstatedir}/cache/ipa/sysupgrade mkdir %{buildroot}%{_usr}/share/ipa/html/ ln -s ../../../..%{_sysconfdir}/ipa/html/ssbrowser.html \ %{buildroot}%{_usr}/share/ipa/html/ssbrowser.html @@ -620,6 +621,7 @@ fi %attr(755,root,root) %{plugin_dir}/libipa_cldap.so %dir %{_localstatedir}/lib/ipa %attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysrestore +%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysupgrade %dir %{_localstatedir}/cache/ipa %attr(700,apache,apache) %dir %{_localstatedir}/cache/ipa/sessions %attr(755,root,root) %{_libdir}/krb5/plugins/kdb/ipadb.so @@ -701,6 +703,9 @@ fi %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt %changelog +* Fri Jun 8 2012 Martin Kosek - 2.99.0-32 +- Add directory /var/lib/ipa/sysupgrade for package upgrade metadata + * Mon Jun 4 2012 Alexander Bokovoy - 2.99.0-31 - Add python-crypto to build dependencies for AD server-side code diff --git a/install/Makefile.am b/install/Makefile.am index 4d24d072d..5670f9bd9 100644 --- a/install/Makefile.am +++ b/install/Makefile.am @@ -19,11 +19,14 @@ SUBDIRS = \ install-exec-local: mkdir -p $(DESTDIR)$(localstatedir)/lib/ipa/sysrestore chmod 700 $(DESTDIR)$(localstatedir)/lib/ipa/sysrestore + mkdir -p $(DESTDIR)$(localstatedir)/lib/ipa/sysupgrade + chmod 700 $(DESTDIR)$(localstatedir)/lib/ipa/sysupgrade mkdir -p $(DESTDIR)$(localstatedir)/cache/ipa/sessions chmod 700 $(DESTDIR)$(localstatedir)/cache/ipa/sessions uninstall-local: -rmdir $(DESTDIR)$(localstatedir)/lib/ipa/sysrestore + -rmdir $(DESTDIR)$(localstatedir)/lib/ipa/sysupgrade -rmdir $(DESTDIR)$(localstatedir)/lib/ipa -rmdir $(DESTDIR)$(localstatedir)/cache/ipa/sessions -rmdir $(DESTDIR)$(localstatedir)/cache/ipa diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install index 871bfd52a..61c2b9d8c 100755 --- a/install/tools/ipa-server-install +++ b/install/tools/ipa-server-install @@ -48,6 +48,7 @@ from ipaserver.install import ntpinstance from ipaserver.install import certs from ipaserver.install import cainstance from ipaserver.install import memcacheinstance +from ipaserver.install import sysupgrade from ipaserver.install import service, installutils from ipapython import version @@ -495,6 +496,9 @@ def uninstall(): except CalledProcessError, e: print >>sys.stderr, "Failed to set this machine hostname back to %s (%s)." % (old_hostname, str(e)) + # remove upgrade state file + sysupgrade.remove_upgrade_file() + if fstore.has_files(): root_logger.error('Some files have not been restored, see /var/lib/ipa/sysrestore/sysrestore.index') has_state = False diff --git a/ipapython/sysrestore.py b/ipapython/sysrestore.py index 82817acad..7720fd6e3 100644 --- a/ipapython/sysrestore.py +++ b/ipapython/sysrestore.py @@ -41,7 +41,7 @@ SYSRESTORE_STATEFILE = "sysrestore.state" class FileStore: """Class for handling backup and restore of files""" - def __init__(self, path = SYSRESTORE_PATH): + def __init__(self, path = SYSRESTORE_PATH, index_file = SYSRESTORE_INDEXFILE): """Create a _StoreFiles object, that uses @path as the base directory. @@ -49,7 +49,7 @@ class FileStore: about the original location of the saved files. """ self._path = path - self._index = self._path + "/" + SYSRESTORE_INDEXFILE + self._index = os.path.join(self._path, index_file) self.random = random.Random() @@ -279,7 +279,7 @@ class StateFile: enabled=False """ - def __init__(self, path = SYSRESTORE_PATH): + def __init__(self, path = SYSRESTORE_PATH, state_file = SYSRESTORE_STATEFILE): """Create a StateFile object, loading from @path. The dictionary @modules, a member of the returned object, @@ -290,7 +290,7 @@ class StateFile: The keys in these latter dictionaries are arbitrary strings and the values may either be strings or booleans. """ - self._path = path+"/"+SYSRESTORE_STATEFILE + self._path = os.path.join(path, state_file) self.modules = {} @@ -359,25 +359,44 @@ class StateFile: self.save() - def restore_state(self, module, key): + def get_state(self, module, key): """Return the value of an item of system state from @module, - identified by the string @key, and remove it from the backed - up system state. + identified by the string @key. If the item doesn't exist, #None will be returned, otherwise the original string or boolean value is returned. """ - if not self.modules.has_key(module): return None - if not self.modules[module].has_key(key): - return None + return self.modules[module].get(key, None) - value = self.modules[module][key] - del self.modules[module][key] + def delete_state(self, module, key): + """Delete system state from @module, identified by the string + @key. - self.save() + If the item doesn't exist, no change is done. + """ + try: + del self.modules[module][key] + except KeyError: + pass + else: + self.save() + + def restore_state(self, module, key): + """Return the value of an item of system state from @module, + identified by the string @key, and remove it from the backed + up system state. + + If the item doesn't exist, #None will be returned, otherwise + the original string or boolean value is returned. + """ + + value = self.get_state(module, key) + + if value is not None: + self.delete_state(module, key) return value diff --git a/ipaserver/install/sysupgrade.py b/ipaserver/install/sysupgrade.py new file mode 100644 index 000000000..c508d2bbd --- /dev/null +++ b/ipaserver/install/sysupgrade.py @@ -0,0 +1,47 @@ +# Authors: Martin Kosek +# +# Copyright (C) 2012 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +import os.path + +from ipapython import sysrestore +from ipapython.ipa_log_manager import * + +STATEFILE_DIR = '/var/lib/ipa/sysupgrade' +STATEFILE_FILE = 'sysupgrade.state' + +_sstore = sysrestore.StateFile(STATEFILE_DIR, STATEFILE_FILE) + +def get_upgrade_state(module, state): + global _sstore + return _sstore.get_state(module, state) + +def set_upgrade_state(module, state, value): + global _sstore + _sstore.backup_state(module, state, value) + +def remove_upgrade_state(module, state): + global _sstore + _sstore.delete_state(module, state) + +def remove_upgrade_file(): + try: + os.remove(os.path.join(STATEFILE_DIR, STATEFILE_FILE)) + except Exception, e: + root_logger.debug('Cannot remove sysupgrade state file: %s', e) -- cgit