ipa/freeipa-4.8.9-support-older...

283 lines
10 KiB
Diff

From 071e283b19e925bea596a25b4758ab2cbc657914 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 11 Aug 2020 10:47:05 -0400
Subject: [PATCH 1/3] Fall back to old server installation detection when
needed
If there is no installation section the the install pre-dated
this new method of detecting a successful installation, fall back
to that.
https://pagure.io/freeipa/issue/8458
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
---
ipalib/facts.py | 31 ++++++++++++++++++++++++++++-
ipaserver/install/installutils.py | 4 ----
ipaserver/install/server/install.py | 3 ++-
ipaserver/install/server/upgrade.py | 7 +++++--
4 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/ipalib/facts.py b/ipalib/facts.py
index 5106fc2ac5..d78c1a2275 100644
--- a/ipalib/facts.py
+++ b/ipalib/facts.py
@@ -6,17 +6,46 @@
Facts about the installation
"""
+import logging
import os
from . import sysrestore
from ipaplatform.paths import paths
+logger = logging.getLogger(__name__)
+
+# Used to determine install status
+IPA_MODULES = [
+ 'httpd', 'kadmin', 'dirsrv', 'pki-tomcatd', 'install', 'krb5kdc', 'named']
+
def is_ipa_configured():
"""
Use the state to determine if IPA has been configured.
"""
sstore = sysrestore.StateFile(paths.SYSRESTORE)
- return sstore.get_state('installation', 'complete')
+ if sstore.has_state('installation'):
+ return sstore.get_state('installation', 'complete')
+
+ # Fall back to older method in case this is an existing installation
+
+ installed = False
+
+ fstore = sysrestore.FileStore(paths.SYSRESTORE)
+
+ for module in IPA_MODULES:
+ if sstore.has_state(module):
+ logger.debug('%s is configured', module)
+ installed = True
+ else:
+ logger.debug('%s is not configured', module)
+
+ if fstore.has_files():
+ logger.debug('filestore has files')
+ installed = True
+ else:
+ logger.debug('filestore is tracking no files')
+
+ return installed
def is_ipa_client_configured(on_master=False):
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 583b1aca0b..13baf494cd 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -63,10 +63,6 @@
logger = logging.getLogger(__name__)
-# Used to determine install status
-IPA_MODULES = [
- 'httpd', 'kadmin', 'dirsrv', 'pki-tomcatd', 'install', 'krb5kdc', 'named']
-
class BadHostError(Exception):
pass
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index b86c3fec15..4d8e3ad78f 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -37,13 +37,14 @@
validate_domain_name,
no_matching_interface_for_ip_address_warning,
)
+from ipalib.facts import IPA_MODULES
from ipaserver.install import (
adtrust, adtrustinstance, bindinstance, ca, dns, dsinstance,
httpinstance, installutils, kra, krbinstance,
otpdinstance, custodiainstance, replication, service,
sysupgrade)
from ipaserver.install.installutils import (
- IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address,
+ BadHostError, get_fqdn, get_server_ip_address,
load_pkcs12, read_password, verify_fqdn, update_hosts_file,
validate_mask)
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index f0d9b746cd..109d1e100e 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1455,8 +1455,11 @@ def upgrade_configuration():
fstore = sysrestore.FileStore(paths.SYSRESTORE)
sstore = sysrestore.StateFile(paths.SYSRESTORE)
- if is_ipa_configured() is None:
- sstore.backup_state('installation', 'complete', True)
+ if not sstore.has_state('installation'):
+ if is_ipa_configured():
+ sstore.backup_state('installation', 'complete', True)
+ else:
+ sstore.backup_state('installation', 'complete', False)
fqdn = api.env.host
From 7d84d919a8f5767ade1dcc380ce4eebadac6a8b5 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 11 Aug 2020 11:12:55 -0400
Subject: [PATCH 2/3] Use is_ipa_configured from ipalib.facts
A couple of places still used the deprecated installutils version.
https://pagure.io/freeipa/issue/8458
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
---
ipaserver/install/installutils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 13baf494cd..a3274d5797 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -665,7 +665,7 @@ def check_server_configuration():
Most convenient use case for the function is in install tools that require
configured IPA for its function.
"""
- if not is_ipa_configured():
+ if not facts.is_ipa_configured():
raise ScriptError("IPA is not configured on this system.",
rval=SERVER_NOT_CONFIGURED)
From 36ecfdbfe4ceedcfe056816cbb22162842fae975 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 11 Aug 2020 13:55:54 -0400
Subject: [PATCH 3/3] ipatests: Add test for is_ipa_configured
Validate that is_ipa_configured() returns True when using either
the original and the new configuration methods. This will allow
older installs to successfully upgrade.
https://pagure.io/freeipa/issue/8458
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
---
.../test_integration/test_installation.py | 88 +++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
index fb19900838..98bdc98ab8 100644
--- a/ipatests/test_integration/test_installation.py
+++ b/ipatests/test_integration/test_installation.py
@@ -21,6 +21,7 @@
from ipalib import x509
from ipalib.constants import DOMAIN_LEVEL_0
+from ipalib.sysrestore import SYSRESTORE_STATEFILE, SYSRESTORE_INDEXFILE
from ipapython.dn import DN
from ipaplatform.constants import constants
from ipaplatform.osinfo import osinfo
@@ -357,6 +358,93 @@ def test_ipa_ca_crt_permissions(self):
assert owner == "root"
assert group == "root"
+ def test_is_ipa_configured(self):
+ """Verify that the old and new methods of is_ipa_installed works
+
+ If there is an installation section then it is the status.
+
+ If not then it will fall back to looking for configured
+ services and files and use that for determination.
+ """
+ def set_installation_state(host, state):
+ """
+ Update the complete value in the installation section
+ """
+ host.run_command(
+ ['python3', '-c',
+ 'from ipalib.install import sysrestore; '
+ 'from ipaplatform.paths import paths;'
+ 'sstore = sysrestore.StateFile(paths.SYSRESTORE); '
+ 'sstore.backup_state("installation", "complete", '
+ '{state})'.format(state=state)])
+
+ def get_installation_state(host):
+ """
+ Retrieve the installation state from new install method
+ """
+ result = host.run_command(
+ ['python3', '-c',
+ 'from ipalib.install import sysrestore; '
+ 'from ipaplatform.paths import paths;'
+ 'sstore = sysrestore.StateFile(paths.SYSRESTORE); '
+ 'print(sstore.get_state("installation", "complete"))'])
+ return result.stdout_text.strip() # a string
+
+ # This comes from freeipa.spec and is used to determine whether
+ # an upgrade is required.
+ cmd = ['python3', '-c',
+ 'import sys; from ipalib import facts; sys.exit(0 '
+ 'if facts.is_ipa_configured() else 1);']
+
+ # This will use the new method since this is a fresh install,
+ # verify that it is true.
+ self.master.run_command(cmd)
+ assert get_installation_state(self.master) == 'True'
+
+ # Set complete to False which should cause the command to fail
+ # This tests the state of a failed or in-process installation.
+ set_installation_state(self.master, False)
+ result = self.master.run_command(cmd, raiseonerr=False)
+ assert result.returncode == 1
+ set_installation_state(self.master, True)
+
+ # Tweak sysrestore.state to drop installation section
+ self.master.run_command(
+ ['sed','-i', r's/\[installation\]/\[badinstallation\]/',
+ os.path.join(paths.SYSRESTORE, SYSRESTORE_STATEFILE)])
+
+ # Re-run installation check and it should fall back to old method
+ # and be successful.
+ self.master.run_command(cmd)
+ assert get_installation_state(self.master) == 'None'
+
+ # Restore installation section.
+ self.master.run_command(
+ ['sed','-i', r's/\[badinstallation\]/\[installation\]/',
+ os.path.join(paths.SYSRESTORE, SYSRESTORE_STATEFILE)])
+
+ # Uninstall and confirm that the old method reports correctly
+ # on uninstalled servers. It will exercise the old method since
+ # there is no state.
+ tasks.uninstall_master(self.master)
+
+ # ensure there is no stale state
+ result = self.master.run_command(r'test -f {}'.format(
+ os.path.join(paths.SYSRESTORE, SYSRESTORE_STATEFILE)),
+ raiseonerr=False
+ )
+ assert result.returncode == 1
+ result = self.master.run_command(r'test -f {}'.format(
+ os.path.join(paths.SYSRESTORE, SYSRESTORE_INDEXFILE)),
+ raiseonerr=False
+ )
+ assert result.returncode == 1
+
+ # Now run is_ipa_configured() and it should be False
+ result = self.master.run_command(cmd, raiseonerr=False)
+ assert result.returncode == 1
+
+
class TestInstallWithCA_KRA1(InstallTestBase1):
@classmethod