283 lines
10 KiB
Diff
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
|