From 04ba21aaca9c376abab36cf75d764507a3b14802 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 10 Oct 2011 15:25:15 +0300 Subject: Add support for systemd environments and use it to support Fedora 16 https://fedorahosted.org/freeipa/ticket/1192 --- Makefile | 2 +- freeipa.spec.in | 71 ++++++++++++++ init/systemd/ipa.service | 14 +++ install/tools/ipactl | 12 ++- ipapython/config.py | 2 +- ipapython/ipautil.py | 90 +++++++++++++++++ ipapython/platform/base.py | 14 +-- ipapython/platform/fedora16.py | 113 ++++++++++++++++++++++ ipapython/platform/redhat.py | 61 +++--------- ipapython/platform/systemd.py | 204 +++++++++++++++++++++++++++++++++++++++ ipaserver/install/cainstance.py | 4 +- ipaserver/install/dsinstance.py | 6 +- ipaserver/install/krbinstance.py | 30 ++---- 13 files changed, 538 insertions(+), 85 deletions(-) create mode 100644 init/systemd/ipa.service create mode 100644 ipapython/platform/fedora16.py create mode 100644 ipapython/platform/systemd.py diff --git a/Makefile b/Makefile index 585c6fe11..a024dea32 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ PRJ_PREFIX=freeipa RPMBUILD ?= $(PWD)/rpmbuild TARGET ?= master -SUPPORTED_PLATFORM=redhat +SUPPORTED_PLATFORM ?= redhat # After updating the version in VERSION you should run the version-update # target. diff --git a/freeipa.spec.in b/freeipa.spec.in index ca6d294f5..48aa92c60 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -24,10 +24,17 @@ Source0: freeipa-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %if ! %{ONLY_CLIENT} +%if 0%{?fedora} >= 16 +BuildRequires: 389-ds-base-devel >= 1.2.10 +%else BuildRequires: 389-ds-base-devel >= 1.2.9 +%endif BuildRequires: svrcore-devel BuildRequires: /usr/share/selinux/devel/Makefile BuildRequires: policycoreutils >= %{POLICYCOREUTILSVER} +%if 0%{?fedora} >= 16 +BuildRequires: systemd-units +%endif %endif BuildRequires: nspr-devel BuildRequires: nss-devel @@ -85,11 +92,19 @@ Requires: %{name}-python = %{version}-%{release} Requires: %{name}-client = %{version}-%{release} Requires: %{name}-admintools = %{version}-%{release} Requires: %{name}-server-selinux = %{version}-%{release} +%if 0%{?fedora} >= 16 +Requires(pre): 389-ds-base >= 1.2.10-0.1.a1 +%else Requires(pre): 389-ds-base >= 1.2.9.7-1 +%endif Requires: openldap-clients Requires: nss Requires: nss-tools +%if 0%{?fedora} >= 16 +Requires: krb5-server >= 1.9.1-15 +%else Requires: krb5-server +%endif Requires: krb5-server-ldap Requires: krb5-pkinit-openssl Requires: cyrus-sasl-gssapi%{?_isa} @@ -102,6 +117,11 @@ Requires: python-ldap Requires: python-krbV Requires: acl Requires: python-pyasn1 >= 0.0.9a +%if 0%{?fedora} >= 16 +Requires: systemd-units >= 36-3 +Requires(pre): systemd-units +Requires(post): systemd-units +%endif %if 0%{?fedora} >= 15 Requires: selinux-policy >= 3.9.16-18 %else @@ -109,6 +129,12 @@ Requires: selinux-policy >= 3.9.7-27 %endif Requires(post): selinux-policy-base Requires: slapi-nis >= 0.21 +%if 0%{?fedora} >= 16 +Requires: pki-ca >= 9.0.15 +Requires: pki-silent >= 9.0.15 +# Only tomcat6 greater than this version provides proper systemd support +Requires: tomcat6 >= 6.0.32-17 +%else %if 0%{?fedora} >= 15 Requires: pki-ca >= 9.0.12 Requires: pki-silent >= 9.0.12 @@ -116,13 +142,19 @@ Requires: pki-silent >= 9.0.12 Requires: pki-ca >= 9.0.5 Requires: pki-silent >= 9.0.5 %endif +%endif Requires: dogtag-pki-common-theme Requires: dogtag-pki-ca-theme %if 0%{?rhel} Requires: subscription-manager %endif +%if 0%{?fedora} >= 16 +Requires(preun): python systemd-units +Requires(postun): python systemd-units +%else Requires(preun): python initscripts chkconfig Requires(postun): python initscripts chkconfig +%endif # We have a soft-requires on bind. It is an optional part of # IPA but if it is configured we need a way to require versions @@ -251,6 +283,9 @@ package. %build export CFLAGS="$CFLAGS %{optflags}" export CPPFLAGS="$CPPFLAGS %{optflags}" +%if 0%{?fedora} >= 16 +export SUPPORTED_PLATFORM=fedora16 +%endif make version-update cd ipa-client; ../autogen.sh --prefix=%{_usr} --sysconfdir=%{_sysconfdir} --localstatedir=%{_localstatedir} --libdir=%{_libdir} --mandir=%{_mandir}; cd .. %if ! %{ONLY_CLIENT} @@ -315,6 +350,13 @@ mkdir -p %{buildroot}%{_sysconfdir}/httpd/conf.d/ /bin/touch %{buildroot}%{_sysconfdir}/httpd/conf.d/ipa-rewrite.conf mkdir -p %{buildroot}%{_initrddir} install -m755 ipa.init %{buildroot}%{_initrddir}/ipa +%if 0%{?fedora} >= 16 +# Default to systemd initscripts for F16 and above +mkdir -p %{buildroot}%{_unitdir} +install -m 644 init/systemd/ipa.service %{buildroot}%{_unitdir}/ipa.service +%else +install -m755 init/SystemV/ipa.init %{buildroot}%{_initrddir}/ipa +%endif %endif mkdir -p %{buildroot}%{_sysconfdir}/ipa/ @@ -334,7 +376,13 @@ rm -rf %{buildroot} %if ! %{ONLY_CLIENT} %post server if [ $1 = 1 ]; then +%if 0%{?fedora} >= 16 +# Use systemd scheme + /bin/systemctl --system daemon-reload 2>&1 || : +%else +# Use SystemV scheme only before F16 /sbin/chkconfig --add ipa +%endif fi if [ $1 -gt 1 ] ; then /usr/sbin/ipa-upgradeconfig || : @@ -343,13 +391,27 @@ fi %preun server if [ $1 = 0 ]; then +%if 0%{?fedora} >= 16 +# Use systemd scheme + /bin/systemctl --quiet stop ipa.service || : + /bin/systemctl --quiet disable ipa.service || : +%else +# Use SystemV scheme only before F16 /sbin/chkconfig --del ipa /sbin/service ipa stop >/dev/null 2>&1 || : +%endif fi %postun server if [ "$1" -ge "1" ]; then +%if 0%{?fedora} >= 16 +# Use systemd scheme + /bin/systemctl --quiet is-active ipa.service >/dev/null && \ + /bin/systemctl try-restart ipa.service >/dev/null 2>&1 || : +%else +# Use SystemV scheme only before F16 /sbin/service ipa condrestart >/dev/null 2>&1 || : +%endif fi %pre server-selinux @@ -418,7 +480,13 @@ fi %{_sbindir}/ipa-upgradeconfig %{_sbindir}/ipa-compliance %{_sysconfdir}/cron.d/ipa-compliance +%if 0%{?fedora} >= 16 +# Use systemd scheme +%attr(644,root,root) %{_unitdir}/ipa.service +%else +# Use SystemV scheme only before F16 %attr(755,root,root) %{_initrddir}/ipa +%endif %dir %{python_sitelib}/ipaserver %{python_sitelib}/ipaserver/* %dir %{_usr}/share/ipa @@ -548,6 +616,9 @@ fi %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/default.conf %changelog +* Mon Oct 10 2011 Alexander Bokovoy - 2.99.0-6 +- Default to systemd for Fedora 16 and onwards + * Tue Sep 13 2011 Alexander Bokovoy - 2.99.0-5 - Make sure platform adaptation is packaged in -python sub-package diff --git a/init/systemd/ipa.service b/init/systemd/ipa.service new file mode 100644 index 000000000..ba27d1dfd --- /dev/null +++ b/init/systemd/ipa.service @@ -0,0 +1,14 @@ +[Unit] +Description=Identity, Policy, Audit +Requires=syslog.target network.target +After=syslog.target network.target + +[Service] +Type=oneshot +ExecStart=/usr/sbin/ipactl start +ExecStop=/usr/sbin/ipactl stop +RemainAfterExit=yes +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target diff --git a/install/tools/ipactl b/install/tools/ipactl index 4055cf91b..13e4b007a 100755 --- a/install/tools/ipactl +++ b/install/tools/ipactl @@ -24,7 +24,7 @@ try: from ipaserver.install import service from ipapython import services as ipaservices from ipaserver.install.dsinstance import config_dirname, realm_to_serverid - from ipaserver.install.installutils import is_ipa_configured + from ipaserver.install.installutils import is_ipa_configured, wait_for_open_ports, wait_for_open_socket from ipapython import sysrestore from ipapython import config from ipalib import api, errors @@ -32,6 +32,7 @@ try: import logging import ldap import ldap.sasl + import ldapurl import socket except ImportError: print >> sys.stderr, """\ @@ -117,6 +118,15 @@ def get_config(): attrs = ['cn', 'ipaConfigString'] try: + # systemd services are so fast that we come here before + # Directory Server actually starts listening. Wait for + # the socket/port be really available. + lurl = ldapurl.LDAPUrl(api.env.ldap_uri) + if lurl.urlscheme == 'ldapi': + wait_for_open_socket(lurl.hostport, timeout=6) + else: + (host,port) = lurl.hostport.split(':') + wait_for_open_ports(host, [port], timeout=6) con = ldap.initialize(api.env.ldap_uri) con.sasl_interactive_bind_s('', SASL_EXTERNAL) res = con.search_st(base, diff --git a/ipapython/config.py b/ipapython/config.py index 051e39f92..4e0fb11b8 100644 --- a/ipapython/config.py +++ b/ipapython/config.py @@ -178,7 +178,7 @@ def __discover_config(discover_server = True): if not config.default_domain: #try once with REALM -> domain - dom_name = config.default_realm.lower() + dom_name = config.default_realm.lower() #pylint: disable=E1103 name = "_ldap._tcp."+dom_name+"." rs = ipapython.dnsclient.query(name, ipapython.dnsclient.DNS_C_IN, ipapython.dnsclient.DNS_T_SRV) rl = len(rs) diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index 6e037926c..49fc64cea 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -1185,3 +1185,93 @@ def get_ipa_basedn(conn): return None +def config_replace_variables(filepath, replacevars=dict(), appendvars=dict()): + """ + Take a key=value based configuration file, and write new version + with certain values replaced or appended + + All (key,value) pairs from replacevars and appendvars that were not found + in the configuration file, will be added there. + + It is responsibility of a caller to ensure that replacevars and + appendvars do not overlap. + + It is responsibility of a caller to back up file. + + returns dictionary of affected keys and their previous values + + One have to run restore_context(filepath) afterwards or + security context of the file will not be correct after modification + """ + pattern = re.compile(''' +(^ + \s* + (?P