diff --git a/ipatests/prci_definitions/nightly_master.yaml b/ipatests/prci_definitions/nightly_master.yaml index 2dd44c8fb..2303b1be8 100644 --- a/ipatests/prci_definitions/nightly_master.yaml +++ b/ipatests/prci_definitions/nightly_master.yaml @@ -1205,17 +1205,17 @@ jobs: timeout: 3600 topology: *master_1repl - fedora-29/test_automount_locations: + fedora-29/nfs: requires: [fedora-29/build] priority: 50 job: class: RunPytest args: build_url: '{fedora-29/build_url}' - test_suite: test_integration/test_automount_locations.py + test_suite: test_integration/test_nfs.py::TestNFS template: *ci-master-f29 - timeout: 6300 - topology: *master_1repl + timeout: 9000 + topology: *master_3repl_1client fedora-29/mask: requires: [fedora-29/build] diff --git a/ipatests/prci_definitions/nightly_rawhide.yaml b/ipatests/prci_definitions/nightly_rawhide.yaml index f146d0396..53178cda6 100644 --- a/ipatests/prci_definitions/nightly_rawhide.yaml +++ b/ipatests/prci_definitions/nightly_rawhide.yaml @@ -1216,3 +1216,15 @@ jobs: template: *ci-master-frawhide timeout: 3600 topology: *ipaserver + + fedora-rawhide/nfs: + requires: [fedora-rawhide/build] + priority: 50 + job: + class: RunPytest + args: + build_url: '{fedora-rawhide/build_url}' + test_suite: test_integration/test_nfs.py::TestNFS + template: *ci-master-frawhide + timeout: 9000 + topology: *master_3repl_1client diff --git a/ipatests/test_integration/test_automount_locations.py b/ipatests/test_integration/test_automount_locations.py deleted file mode 100644 index 646d1d07a..000000000 --- a/ipatests/test_integration/test_automount_locations.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# Copyright (C) 2018 FreeIPA Contributors see COPYING for license -# - -"""This module provides tests for the automount location feature. -""" - -from __future__ import absolute_import - -import time -import re - -from ipatests.test_integration.base import IntegrationTest -from ipatests.pytest_ipa.integration import tasks - -# give some time for units to stabilize -# otherwise we get transient errors -WAIT_AFTER_INSTALL = 5 -WAIT_AFTER_UNINSTALL = WAIT_AFTER_INSTALL - - -class TestAutomountInstallUninstall(IntegrationTest): - """ - Test if ipa-client-automount behaves as expected - """ - - num_replicas = 1 - topology = 'star' - - @classmethod - def install(cls, mh): - tasks.install_master(cls.master, setup_dns=False) - client = cls.replicas[0] - tasks.install_client(cls.master, client) - - def test_use_automount_location(self): - - client = self.replicas[0] - - self.master.run_command([ - "ipa", "automountlocation-add", "baltimore" - ]) - - self.master.run_command([ - "ipa", "host-mod", client.hostname, - "--location", "baltimore" - ]) - - # systemctl non-fatal errors will only be displayed - # if ipa-client-automount is launched with --debug - result1 = client.run_command([ - 'ipa-client-automount', '--location', 'baltimore', - '-U', '--debug' - ]) - - # systemctl non-fatal errors will show up like this: - # stderr=Failed to restart nfs-secure.service: \ - # Unit nfs-secure.service not found. - # normal output: - # stderr= - m1 = re.search(r'(?<=stderr\=Failed).+', result1.stderr_text) - # maybe re-use m1.group(0) if it exists. - assert m1 is None - - time.sleep(WAIT_AFTER_INSTALL) - - result2 = client.run_command([ - 'ipa-client-automount', '--uninstall', - '-U', '--debug' - ]) - - m2 = re.search(r'(?<=stderr\=Failed).+', result2.stderr_text) - assert m2 is None - - time.sleep(WAIT_AFTER_UNINSTALL) - - self.master.run_command([ - "ipa", "host-mod", client.hostname, - "--location", "''" - ]) - - self.master.run_command([ - "ipa", "automountlocation-del", "baltimore" - ]) diff --git a/ipatests/test_integration/test_nfs.py b/ipatests/test_integration/test_nfs.py new file mode 100644 index 000000000..d2d5ff83a --- /dev/null +++ b/ipatests/test_integration/test_nfs.py @@ -0,0 +1,257 @@ +# +# Copyright (C) 2018 FreeIPA Contributors see COPYING for license +# + +"""This module provides tests for NFS-related features like + krb5 NFS and automount locations. + + Wishlist + * add automount direct and indirect maps + * add automount /home for the "seattle" location only + * validate it is not available in another location + * krb5 /home for IdM users in test_krb5_nfs_manual_configuration + * krb5 /home for IdM users in test_automount_location + * store nfs configuration in a single place +""" + +from __future__ import absolute_import + +import time +import re + +from ipatests.test_integration.base import IntegrationTest +from ipatests.pytest_ipa.integration import tasks +from ipaplatform.paths import paths + +import os + +# give some time for units to stabilize +# otherwise we get transient errors +WAIT_AFTER_INSTALL = 5 +WAIT_AFTER_UNINSTALL = WAIT_AFTER_INSTALL + + +class TestInit(IntegrationTest): + + @classmethod + def fix_resolv_conf(cls, client, server): + + contents = client.get_file_contents(paths.RESOLV_CONF, + encoding='utf-8') + nameserver = 'nameserver %s\n' % server.ip + if not contents.startswith(nameserver): + contents = nameserver + contents.replace(nameserver, '') + client.run_command([ + '/usr/bin/cp', paths.RESOLV_CONF, + '%s.sav' % paths.RESOLV_CONF + ]) + client.put_file_contents(paths.RESOLV_CONF, contents) + + @classmethod + def restore_resolv_conf(cls, client): + client.run_command([ + '/usr/bin/cp', + '%s.sav' % paths.RESOLV_CONF, + paths.RESOLV_CONF + ]) + + +class TestNFS(TestInit): + + num_replicas = 2 + num_clients = 1 + topology = 'star' + + @classmethod + def install(cls, mh): + + tasks.install_master(cls.master, setup_dns=True) + clients = (cls.clients[0], cls.replicas[0], cls.replicas[1]) + for client in clients: + cls.fix_resolv_conf(client, cls.master) + tasks.install_client(cls.master, client) + client.run_command(["cat", "/etc/resolv.conf"]) + + def cleanup(self): + + nfssrv = self.clients[0] + nfsclt = self.replicas[0] + automntclt = self.replicas[1] + + nfsclt.run_command(["umount", "-a", "-t", "nfs4"]) + nfsclt.run_command(["systemctl", "stop", "rpc-gssd"]) + + nfssrv.run_command(["systemctl", "stop", "nfs-server"]) + nfssrv.run_command(["systemctl", "disable", "nfs-server"]) + nfssrv.run_command([ + "rm", "-f", "/etc/exports.d/krbnfs.exports", + "/etc/exports.d/stdnfs.exports" + ]) + + nfssrv.run_command(["rm", "-rf", "/exports"]) + + tasks.uninstall_client(nfsclt) + tasks.uninstall_client(nfssrv) + self.master.run_command([ + "ipa", "host-mod", automntclt.hostname, + "--location", "''" + ]) + # not strictly necessary, but this exercises automountlocation-del + self.master.run_command([ + "ipa", "automountlocation-del", "seattle" + ]) + nfsclt.run_command(["systemctl", "restart", "nfs-utils"]) + nfssrv.run_command(["systemctl", "restart", "nfs-utils"]) + for client in (nfssrv, nfsclt, automntclt): + self.restore_resolv_conf(client) + tasks.uninstall_master(self.master) + + def test_prepare_users(self): + + users = { + "athena": "p", + "euripides": "s" + } + temp_pass = 'temppass' + for user in users: + self.master.run_command([ + "ipa", "user-add", + "%s" % user, "--first", "%s" % user, + "--last", "%s" % users[user], + '--password'], stdin_text=temp_pass + ) + self.master.run_command(["kdestroy", "-A"]) + password = "Secret123" + user_kinit = "%s\n%s\n%s\n" % (temp_pass, password, password) + self.master.run_command( + ['kinit', user], stdin_text=user_kinit + ) + self.master.run_command(["kdestroy", "-A"]) + tasks.kinit_admin(self.master) + + def test_krb5_nfsd(self): + + nfssrv = self.clients[0] + + # NFS keytab management + self.master.run_command([ + "ipa", "service-add", "nfs/%s" % nfssrv.hostname + ]) + nfssrv.run_command([ + "ipa-getkeytab", "-p", "nfs/%s" % nfssrv.hostname, + "-k", "/etc/krb5.keytab" + ]) + nfssrv.run_command(["systemctl", "restart", "nfs-server"]) + nfssrv.run_command(["systemctl", "enable", "nfs-server"]) + time.sleep(WAIT_AFTER_INSTALL) + + basedir = "exports" + exports = { + "krbnfs": "*(sec=krb5p,rw)", + "stdnfs": "*(ro)", + "home": "*(sec=krb5p,rw)" + } + for export in exports: + exportpath = os.sep.join(('', basedir, export)) + exportfile = os.sep.join(( + '', 'etc', 'exports.d', "%s.exports" % export + )) + exportline = " ".join((exportpath, exports[export])) + nfssrv.run_command(["mkdir", "-p", exportpath]) + nfssrv.run_command(["chmod", "770", exportpath]) + nfssrv.put_file_contents(exportfile, exportline) + nfssrv.run_command(["cat", exportfile]) + nfssrv.run_command(["exportfs", "-r"]) + nfssrv.run_command(["exportfs", "-s"]) + + def test_krb5_nfs_manual_configuration(self): + + nfssrv = self.clients[0] + nfsclt = self.replicas[0] + + nfsclt.run_command(["systemctl", "restart", "rpc-gssd"]) + time.sleep(WAIT_AFTER_INSTALL) + mountpoints = ("/mnt/krb", "/mnt/std", "/home") + for mountpoint in mountpoints: + nfsclt.run_command(["mkdir", "-p", mountpoint]) + nfsclt.run_command([ + "systemctl", "status", "gssproxy" + ]) + nfsclt.run_command([ + "systemctl", "status", "rpc-gssd" + ]) + nfsclt.run_command([ + "mount", "-t", "nfs4", "-o", "sec=krb5p,vers=4.0", + "%s:/exports/krbnfs" % nfssrv.hostname, "/mnt/krb", "-v" + ]) + nfsclt.run_command([ + "mount", "-t", "nfs4", "-o", "sec=krb5p,vers=4.0", + "%s:/exports/home" % nfssrv.hostname, "/home", "-v" + ]) + + # TODO leverage users + + def test_automount_location(self): + """ + Test if ipa-client-automount behaves as expected + """ + + nfssrv = self.clients[0] + automntclt = self.replicas[1] + + self.master.run_command([ + "ipa", "automountlocation-add", "seattle" + ]) + self.master.run_command([ + "ipa", "automountmap-add", "seattle", "auto.home" + ]) + self.master.run_command([ + "ipa", "automountkey-add", "seattle", "auto.home", + "--key='*'", "--info=sec=krb5p,vers=4" + " 'rhel8-nfsserver0.laptop.example.org:/export/home/&'" + ]) + self.master.run_command([ + "ipa", "automountkey-add", "seattle", "auto.master", + "--key=/home", "--info=auto.home" + ]) + + self.master.run_command([ + "ipa", "host-mod", automntclt.hostname, + "--location", "seattle" + ]) + + # systemctl non-fatal errors will only be displayed + # if ipa-client-automount is launched with --debug + result1 = automntclt.run_command([ + 'ipa-client-automount', '--location', 'seattle', + '-U', '--debug' + ]) + + # systemctl non-fatal errors will show up like this: + # stderr=Failed to restart nfs-secure.service: \ + # Unit nfs-secure.service not found. + # normal output: + # stderr= + m1 = re.search(r'(?<=stderr\=Failed).+', result1.stderr_text) + # maybe re-use m1.group(0) if it exists. + assert m1 is None + + time.sleep(WAIT_AFTER_INSTALL) + + automntclt.run_command([ + "mount", "-t", "nfs4", "-o", "sec=krb5p,vers=4.0", + "%s:/exports/home" % nfssrv.hostname, "/home", "-v" + ]) + + automntclt.run_command(["umount", "-a", "-t", "nfs4"]) + + result2 = automntclt.run_command([ + 'ipa-client-automount', '--uninstall', + '-U', '--debug' + ]) + + m2 = re.search(r'(?<=stderr\=Failed).+', result2.stderr_text) + assert m2 is None + + time.sleep(WAIT_AFTER_UNINSTALL) + self.cleanup()